i'm trying to make some tests for my rest api but when i start the first test the response body is null and i think it's because i am using CompletableFuture...
@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(SpringExtension.class)
public class UserControllerTests {
@Autowired
private MockMvc mockMvc;
@InjectMocks
private UserRestController controller;
@Test
@WithMockUser(username = "test", password = "test", roles = "ADMIN")
public void tryGetAllUsers_shouldFindAllUsers() throws Exception {
mockMvc.perform(get("/api/v1/user/all").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print());
}
}
Controller class
@GetMapping("/all")
@RolesAllowed("ADMIN")
@ResponseBody
public CompletableFuture<ResponseEntity<Page<User>>> getUsers(@PageableDefault(sort = "id", direction = Sort.Direction.ASC) Pageable pageable) {
return CompletableFuture.supplyAsync(() -> ResponseEntity.ok(service.getUsers(pageable)));
}
I've tried so many ways and asked to so many people but one month later i got no solutions...
CodePudding user response:
Your CompletableFuture is executed but you never retrieve the value using the get()
or join()
method, note that these methods wait for your Supplier to return a value (but will also block your getUsers execution until the supplier's return).
Your method currently returns a reference to the CompletableFuture object (printed java.util.concurrent.CompletableFuture@c4437c4[Not completed]
), thus the body is considered as null.
Based on the looks of your Controller, you should take a look at Spring's WebFlux which is an implementation of the reactive paradigm. More details can be found on the reactor project documentation
CodePudding user response:
You can make MockMvc
to wait for your async response. change the code like this:
public void tryGetAllUsers_shouldFindAllUsers() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/api/v1/user/all")
.accept(MediaType.APPLICATION_JSON))
.andExpect(request().asyncStarted())
.andReturn();
mockMvc
.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andDo(print());
}
I