初始化:
@Autowired
private MockMvc mockMvc;
@MockBean
private ProductServiceImp productServiceImp;
@Autowired
private ObjectMapper objectMapper;
updateProduct Controller 测试方法:
@Test
@Order(3)
public void updateProductController_ShouldReturnOk() throws Exception {
// Arrange
when(productServiceImp.updateProduct(product, 1L)).thenReturn(product);
// Act
ResultActions response = mockMvc.perform(put("/api/products/{id}", 1L)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(product))
);
// Assert
response.andExpectAll(
status().isOk(),
jsonPath("$.title", CoreMatchers.is(product.getTitle()))
);
}
控制器类:
//Note: I have @RequestMapping(value = "api/products") at the top of the class
@PutMapping("/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product product) {
Product updatedProduct = productService.updateProduct(product, id);
return ResponseEntity.ok(updatedProduct);
}
状态代码 200 很好,但 JSON 路径“$.title”似乎没有值。
请求如下:
MockHttpServletRequest:
HTTP Method = PUT
Request URI = /api/products/1
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"246"]
Body = {"id":1,"title":"Fake Product","price":99999999,"rating":{"rate":5.0,"count":1},"category":"Fake Category","description":"Fake description","image":"FakeImage.jpg"}
Session Attrs = {}
回复如下:
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
我尝试从 Controller 类显式返回 body,但这也不起作用。因为,我期待 200 个状态和 Json 数据来交叉检查字段(标题),但我收到 java.lang.AssertionError: No value at JSON path "$.title" 错误。
模拟行为与注册的参数不匹配,并在调用
updateProduct
服务时返回 null。
这是因为从控制器中的请求体解析并传递给服务的
Product
实例与您测试中的不同。
您可以为 Product 类的任何实例注册模拟行为,如下所示:
when(
productServiceImp.updateProduct(
anyLong(), any(Product.class))
.thenReturn(Product.class);
另一种方法是通过重写 Product 对象的
equals
和 hashCode
方法来自定义如何在 Product 对象中执行相等。