我正在尝试在 Spring Boot 应用程序中测试我的控制器的方法。这是一个后端点,它在请求中获取 id,并将此 id 传递给服务:
@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);
}
}
控制器的此方法的测试:
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");
}
}
当我运行此测试时,执行了 post 请求,但正文为空:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /administration
Parameters = {}
Headers = {Content-Type=[application/json]}
Body = <no character encoding set>
Session Attrs = {}
似乎,即使我在测试中设置了内容,它也没有出现在我发送的请求中。而且,事实上,测试失败了:
Argument(s) are different! Wanted: "1234"
Actual invocation has different arguments: null
我在这里错过了什么?如何使用 MockMvc 设置请求正文?
尝试使用 .characterEncoding("utf-8"))
:
MvcResult result = mvc.perform(post("/administration")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
.characterEncoding("utf-8"))
.andExpect(status().isOk())
.andReturn();
另一种选择(受@stelios-anastasakis答案的启发(是在Content-Type
标头中提供字符编码:
MvcResult result = mvc.perform(post("/administration")
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.content(json)
.andExpect(status().isOk())
.andReturn();
请注意,我们在这里使用 MediaType.APPLICATION_JSON_UTF8_VALUE
而不是 MediaType.APPLICATION_JSON
。
mockMvc.perform(post( "/request")
.content(objectMapper.writeValueAsString(requestBody))
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andDo(print())
.andExpect(status().isOk());
您肯定缺少方法参数的注释。
public @ResponseBody ResponseEntity<String> deleteByMessageId(String id)
应该是这样的:
public @ResponseBody ResponseEntity<String> deleteByMessageId(@RequestParam("id") String id)
如果要将其用作请求参数。
在这里查看Spring MVC文档。当然,编写测试取决于您对此处 id 的期望。