问题
I am trying to test a method of my controller in a Spring Boot application. This is a post endpoint, which gets an id in a request and it passes on this id to a service:
@Slf4j
@Controller
public class AdministrationController {
private final AdministrationService administrationService;
@Autowired
public AdministrationController(AdministrationService administrationService) {
this.administrationService = administrationService;
}
@PostMapping("/administration")
public @ResponseBody ResponseEntity<String> deleteByMessageId(String id) {
return new ResponseEntity<>(administrationService.deleteMessageById(id), HttpStatus.OK);
}
}
The test for this method of the controller:
RunWith(SpringRunner.class)
@WebMvcTest(AdministrationController.class)
public class AdministrationControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private AdministrationService service;
@Test
public void
deleteByMessageId_whenCalled_thenServiceMethodIsCalledWithRequestParameters() throws Exception {
Object randomObj = new Object() {
public final String id = "1234";
};
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(randomObj);
MvcResult result = mvc.perform(
post("/administration")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andReturn();
verify(service, times(1)).deleteMessageById("1234");
}
}
When I run this test, the post request is executed, but with an empty body:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /administration
Parameters = {}
Headers = {Content-Type=[application/json]}
Body = <no character encoding set>
Session Attrs = {}
It seems, even though I set the content in my test, it does not appear in the request I am sending. And, indeed, the test fails:
Argument(s) are different! Wanted: "1234"
Actual invocation has different arguments: null
What am I missing here? How can I set the request body with MockMvc?
回答1:
Try to use .characterEncoding("utf-8"))
:
MvcResult result = mvc.perform(post("/administration")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
.characterEncoding("utf-8"))
.andExpect(status().isOk())
.andReturn();
回答2:
Another option (that is inspired by @stelios-anastasakis answer) is to provide character encoding within the Content-Type
header:
MvcResult result = mvc.perform(post("/administration")
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.content(json)
.andExpect(status().isOk())
.andReturn();
Note that we use MediaType.APPLICATION_JSON_UTF8_VALUE
instead of MediaType.APPLICATION_JSON
here.
回答3:
You are surely missing the annotation for your method's parameter.
public @ResponseBody ResponseEntity<String> deleteByMessageId(String id)
Should be something like:
public @ResponseBody ResponseEntity<String> deleteByMessageId(@RequestParam("id") String id)
If you want to use it as a request parameter.
Take a look at the Spring MVC documentation here. Of course writing the test depends on how you expect the id here.
来源:https://stackoverflow.com/questions/49956208/spring-controller-testing-with-mockmvc-post-method