0

I have this REST controller

@RequestMapping(path = "/hello", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
@ApiOperation(code = CREATED, value = "Blah", response = SomeResponse.class)
@ApiResponses(value = {
        @ApiResponse(code = CREATED, message = "blah")
})
public DeferredResult<SomeResponse> hello(@RequestBody final SomeRequest req) {

    DeferredResult<SomeResponse> callback = new DeferredResult<>();
    if (req.someProperty.equals("notimportant")) {
        // return a new SomeResponse obj
        SomeResponse sr = new SomeResponse();
        sr.setOneThing("whocares");
        sr.andAnother("snore");

        //...?
    } else {
        // does something asynchronously
        someService.doSomething(req, callback::setResult);
    }
    return callback;
}

It returns a DeferredResult<>. I want to just return a response under a certain condition (see the if() condition above). What's the best way to go about this? Do I create another thread and call callback.setResult()?

Another question is how I test this (using MockMVC) :

@Test
public void testWhatever() throws Exception {
    SomeRequest request = createRequest();
    String requestContent = this.xmlObjectMapper.writeValueAsString(request);

    MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.post("/api/hello")
            .contentType(MediaType.APPLICATION_XML).content(requestContent).accept(MediaType.APPLICATION_XML))
            .andReturn();

    this.mockMvc.perform(asyncDispatch(mvcResult)).andExpect(MockMvcResultMatchers.status().isCreated())
            .andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_XML));

    String responseString = mvcResult.getResponse().getContentAsString();
    SomeResponse resp = this.xmlObjectMapper.readValue(responseString,SomeResponse.class);

    Assert.assertNotNull(resp);
    // more assertions...
}

This isn't doing anything, getting a NPE. Any clarifications appreciated, thanks!

1 Answers1

1

Think I have something working. In the REST controller, inside the if() condition:

new Thread(() -> callback.setResult(someResponse)).start();

And the unit test, I added a andReturn() to the second perform()... block:

MvcResult mvcResult2 = this.mockMvc.perform(asyncDispatch(mvcResult)).andExpect(MockMvcResultMatchers.status().isCreated())
     .andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_XML)).andReturn();

String responseString = mvcResult2.getResponse().getContentAsString();

Seems to work...