使用MockMvc post方法测试Spring Controller

han*_*ris 6 unit-testing spring-mvc mockito spring-boot 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器的这种方法的测试:

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");
}
Run Code Online (Sandbox Code Playgroud)

}

当我运行此测试时,执行post请求,但是使用空体:

MockHttpServletRequest:
  HTTP Method = POST
  Request URI = /administration
   Parameters = {}
      Headers = {Content-Type=[application/json]}
         Body = <no character encoding set>
Session Attrs = {}
Run Code Online (Sandbox Code Playgroud)

看来,即使我在测试中设置内容,它也不会出现在我发送的请求中.事实上,测试失败了:

Argument(s) are different! Wanted: "1234"
Actual invocation has different arguments: null
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?如何使用MockMvc设置请求正文?

ste*_*kis 11

尝试使用.characterEncoding("utf-8")):

MvcResult result = mvc.perform(post("/administration")
    .contentType(MediaType.APPLICATION_JSON)
    .content(json)
    .characterEncoding("utf-8"))
    .andExpect(status().isOk())
    .andReturn();
Run Code Online (Sandbox Code Playgroud)

  • 我想我知道李·米多来自哪里。顺序并不重要。问题是您的代码中某处有一个额外的括号,或者您缺少一个括号。.andExpect() 在您关闭 mvc.perform() 之后出现。.andExpect() 不会链接到 post()。我刚才正好遇到这个问题。 (2认同)

gal*_*ics -1

您肯定缺少方法参数的注释。

public @ResponseBody ResponseEntity<String> deleteByMessageId(String id)
Run Code Online (Sandbox Code Playgroud)

应该是这样的:

public @ResponseBody ResponseEntity<String> deleteByMessageId(@RequestParam("id") String id)
Run Code Online (Sandbox Code Playgroud)

如果你想用它作为请求参数。

请查看此处的 Spring MVC 文档。当然,编写测试取决于您对这里的 id 的期望。