首页 > 解决方案 > 使用 mockito 测试 POST 请求控制器

问题描述

我正在尝试测试客户端发送到服务器的对象是否真的被控制器使用 mockito 添加到数据库中。所以我想测试服务器的响应以及发送的对象是否真的保存在数据库中。这是我在代码方面的内容=

我的测试:

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest
{
@Autowired
private MockMvc mockMvc;

@MockBean
private UserRepository userRepository;

@Test
public void testAddUserToDb() throws Exception
{
    User objToAdd = new User();
    objToAdd.setId(1);
    objToAdd.setUserID(3);
    objToAdd.setScore(55);
    objToAdd.setName("Tom");

    Gson gson = new Gson();
    String jsonString = gson.toJson(objToAdd);

    when(userRepository.save(any(User.class))).thenReturn(objToAdd);

    mockMvc.perform(post("/user/add").contentType(MediaType.APPLICATION_JSON_UTF8).content(jsonString))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
            .andExpect(jsonPath("$.id").value(1))
            .andExpect(jsonPath("$.userID").value(3))
            .andExpect(jsonPath("$.score").value(55))
            .andExpect(jsonPath("$.name").value("Tim"));

    ArgumentCaptor<User> userArgumentCaptor = ArgumentCaptor.forClass(User.class);
    verify(userRepository, times(1)).save(userArgumentCaptor.capture());
    verifyNoMoreInteractions(userRepository);

    User userArgument = userArgumentCaptor.getValue();
    assertEquals(is(1), userArgument .getId());
    assertEquals(is("Tom"), userArgument .getName());
    assertEquals(is(3), userArgument .getUserID());
    assertEquals(is(55), userArgument .getScore());
}
}

我的控制器方法:

@RestController
@RequestMapping("/user")
public class UserController
{
@Autowired
private UserRepository userRepository;

@PostMapping("/add")
public ResponseEntity AddUser(@RequestBody User user) throws Exception
{
    userRepository.save(user);
    return ResponseEntity.ok(HttpStatus.OK);
}
}

错误日志:

MockHttpServletRequest:
  HTTP Method = POST
  Request URI = /user/add
   Parameters = {}
      Headers = [Content-Type:"application/json;charset=UTF-8"]
         Body = {"id":1,"userID":3,"name":"veg","score":55}
Session Attrs = {}

... not so important code later ...

MockHttpServletResponse:
       Status = 200
Error message = null
      Headers = [Content-Type:"application/json;charset=UTF-8"]
 Content type = application/json;charset=UTF-8
         Body = "OK"
Forwarded URL = null
   Redirected URL = null
          Cookies = []

java.lang.AssertionError: No value at JSON path "$.id"

at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:295)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:98)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.lambda$value$2(JsonPathResultMatchers.java:111)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:195)
at spring.controller.UserControllerTest.AddUser(UserControllerTest.java:59)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

标签: javapostrequestmockitoresponse

解决方案


期望(类似字符串.andExpect(jsonPath("$.id").value(1)))用于检查响应,而不是请求。您的响应只是200 OK没有响应主体(根据您的控制器)。

以下应该可以正常工作:

mockMvc.perform(post("/user/add")
    .contentType(MediaType.APPLICATION_JSON_UTF8)
    .content(jsonString))
    .andExpect(status().isOk());

推荐阅读