【问题标题】:Testing POST request controller with mockito使用 mockito 测试 POST 请求控制器
【发布时间】:2019-03-14 22:17:49
【问题描述】:

我正在尝试测试客户端发送到服务器的对象是否真的被控制器使用 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)

【问题讨论】:

    标签: java post request mockito response


    【解决方案1】:

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

    以下应该可以正常工作:

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

    【讨论】:

    • 这部分.content(jsonString))检查来自客户端的请求,这部分.andExpect(status().isOk())检查发送的响应是真的吗?
    • 是的,perform()里面的东西都是和request有关的,expects和response有关
    • 如果我要使用 ResponseEntity 来响应一个对象,那么我应该如何测试它。例如,我的控制器中有以下代码:@PostMapping("/add") public ResponseEntity AddUser(@RequestBody User user) throws Exception { userRepository.save(user); return ResponseEntity&lt;User&gt;(user, HttpStatus.OK); }
    • 然后您可以将“expects”与结果匹配器一起使用(就像您最初所做的那样)
    • 好的,我现在明白了。非常感谢您的帮助 :)
    猜你喜欢
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多