I'm testing a @RestController
POST endpoint using MockMvc
.
In this test, the MockHttpServletResponse
content is always empty & the content type is not set.
I checked the controller method; it's getting called and returns the right response.
The status code is correctly set to 201 though, in the test.
Here's the test :
@Test
public void testBookCreation() throws Exception {
var response = mockMvc.perform(
MockMvcRequestBuilders
.post("/books/create")
.contentType(MediaType.APPLICATION_JSON)
.content(
jsonb.toJson(new Book("KR","K & R",5,8))
)
).andExpect(
MockMvcResultMatchers.status().isCreated()
).andExpect(
MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)
).andExpect(
MockMvcResultMatchers.jsonPath("$.author").exists()
).andDo((result)->{
System.out.println(result.getResolvedException());
System.out.println(result.getResponse());
}).andReturn();
}
and here's the controller method:
@PostMapping("/create")
@ResponseStatus(code=HttpStatus.CREATED,reason="Book created")
public Book makeBook(@RequestBody Book b ) {
var res = bookRepository.save(b);
System.out.println(res);
return res;
}
I think the problem is with the test and not the controller itself.
The documentation for ResponseStatus
states the following:
Warning: when using this annotation on an exception class, or when setting the reason attribute of this annotation, the HttpServletResponse.sendError method will be used.
Meaning that you will receive a response of following shape, no matter what would be the response sent payload in your controller:
{
"timestamp":"",
"status":201,
"error":"Created",
"message":"",
"path":"/books/create"
}
You should then remove the reason
field for the ReponseStatus
annotation:
@PostMapping("/create")
@ResponseStatus(code=HttpStatus.CREATED)
public Book makeBook(@RequestBody Book b ) {
var res = bookRepository.save(b);
System.out.println(res);
return res;
}