使用MockMvc后置方法进行弹簧控制器测试



我正在尝试在 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 的期望。

相关内容

  • 没有找到相关文章

最新更新