jsonPath在Junit5的Spring Boot中与MockMVC的转换问题

huangapple go评论113阅读模式
英文:

jsonPath cast issue in Junit5 spring boot with MockMVC

问题

我有以下测试案例和导入项

  1. import org.springframework.http.MediaType;
  2. import org.springframework.test.context.junit.jupiter.SpringExtension;
  3. import org.springframework.test.web.servlet.MockMvc;
  4. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
  5. import static org.assertj.core.internal.bytebuddy.matcher.ElementMatchers.is;
  6. import static org.mockito.Mockito.doReturn;
  7. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
  8. @Test
  9. @DisplayName("根据指定的Id返回产品")
  10. void shouldReturnProductBasedOnTheSpecifiedId() throws Exception {
  11. String Id = java.util.UUID.randomUUID().toString();
  12. ProductViewModel productViewModel = new ProductViewModel(Id, "Product 1", 100, "Product 1 description", 0);
  13. doReturn(productViewModel).when(productService).findById(Id);
  14. mockMvc.perform(get(String.format("/api/v1/product/%s", Id)))
  15. //验证响应代码和内容类型
  16. .andExpect(status().isOk())
  17. .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
  18. //验证头部
  19. .andExpect(header().string(HttpHeaders.ETAG, String.format("\"%s\"", Id)))
  20. .andExpect(header().string(HttpHeaders.LOCATION, String.format("/%s", Id)))
  21. //验证返回字段
  22. .andExpect(jsonPath("$.id", is(Id)));
  23. //.andExpect((ResultMatcher) jsonPath("$.name", is("Product 1")))
  24. //.andExpect((ResultMatcher) jsonPath("$.price", is(100)))
  25. //.andExpect((ResultMatcher) jsonPath("$.description", is("Product 1 description")))
  26. //.andExpect((ResultMatcher) jsonPath("$.version", is(0)));
  27. }

出现错误:

jsonPath在Junit5的Spring Boot中与MockMVC的转换问题

如果我对对象进行类型转换,会收到类型转换错误消息。

jsonPath在Junit5的Spring Boot中与MockMVC的转换问题

英文:

I have the below test case with imports as

  1. import org.springframework.http.MediaType;
  2. import org.springframework.test.context.junit.jupiter.SpringExtension;
  3. import org.springframework.test.web.servlet.MockMvc;
  4. import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
  5. import static org.assertj.core.internal.bytebuddy.matcher.ElementMatchers.is;
  6. import static org.mockito.Mockito.doReturn;
  7. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
  8. @Test
  9. @DisplayName("Should return product based on the specified Id")
  10. void shouldReturnProductBasedOnTheSpecifiedId() throws Exception {
  11. String Id = java.util.UUID.randomUUID().toString();
  12. ProductViewModel productViewModel = new ProductViewModel(Id, "Product 1", 100, "Product 1 description", 0);
  13. doReturn(productViewModel).when(productService).findById(Id);
  14. mockMvc.perform(get(String.format("/api/v1/product/%s", Id)))
  15. //Validate the response code and content type
  16. .andExpect(status().isOk())
  17. .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
  18. //validate the headers
  19. .andExpect(header().string(HttpHeaders.ETAG, String.format("\"%s\"", Id)))
  20. .andExpect(header().string(HttpHeaders.LOCATION, String.format("/%s", Id)))
  21. //Validate the return fields
  22. .andExpect(jsonPath("$.id", is(Id)));
  23. //.andExpect((ResultMatcher) jsonPath("$.name", is("Product 1")))
  24. //.andExpect((ResultMatcher) jsonPath("$.price", is(100)))
  25. //.andExpect((ResultMatcher) jsonPath("$.description", is("Product 1 description")))
  26. //.andExpect((ResultMatcher) jsonPath("$.version", is(0)));
  27. }

Getting an error as

jsonPath在Junit5的Spring Boot中与MockMVC的转换问题

If I cast the object I get an cast error message.

jsonPath在Junit5的Spring Boot中与MockMVC的转换问题

答案1

得分: 2

  1. 有几种方法可以解决这个问题:
  2. ## 包括单个 Json 属性的比较 ##
  3. ```java
  4. import org.springframework.test.web.servlet.MockMvc;
  5. import static org.springframework.http.MediaType.APPLICATION_JSON;
  6. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
  7. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
  8. import static org.hamcrest.core.Is.is;
  9. mockMvc.perform(get(String.format("/api/v1/product/%s", Id))
  10. .andExpect(content().contentType(APPLICATION_JSON_VALUE))
  11. .andExpect(jsonPath("$.id", is(Id))));

与你的示例不同之处在于 "is import"


将 Json 响应反序列化为类并比较对象

这是一种更通用且可重复使用的方法。

  1. 使用 Json 反序列化方法将其转换为一个已知类实例的对象。
  2. 在测试中比较预期对象与接收到的对象。

你可以在以下 链接 中看到完整的示例,更具体地在测试中:

  1. static Stream<Arguments> findByIdWithOrderLines_validIdTestCases() {
  2. PizzaDto pizzaDto = new PizzaDto((short)1, "Carbonara", 7.50);
  3. OrderLineDto orderLineDto = new OrderLineDto(10, 1, pizzaDto, (short)2, 15D);
  4. OrderDto dto = new OrderDto(1, "Order 1", new Date(), asList(orderLineDto));
  5. return Stream.of(
  6. //@formatter:off
  7. // serviceResult, expectedResultHttpCode, expectedBodyResult
  8. Arguments.of( empty(), NOT_FOUND, null ),
  9. Arguments.of( of(dto), OK, dto )
  10. ); //@formatter:on
  11. }
  12. @ParameterizedTest
  13. @SneakyThrows
  14. @WithMockUser(authorities = {Constants.ROLE_ADMIN})
  15. @MethodSource("findByIdWithOrderLines_validIdTestCases")
  16. @DisplayName("findByIdWithOrderLines: 给定 Id 验证验证,然后返回适当的 Http code")
  17. public void findByIdWithOrderLines_whenGivenIdVerifiesValidations_thenSuitableHttpCodeIsReturned(Optional<OrderDto> serviceResult,
  18. HttpStatus expectedResultHttpCode, OrderDto expectedBodyResult) {
  19. // Given
  20. Integer validOrderId = 1;
  21. // When
  22. when(mockOrderService.findByIdWithOrderLines(validOrderId)).thenReturn(serviceResult);
  23. ResultActions result = mockMvc.perform(get(RestRoutes.ORDER.ROOT + "/" + validOrderId + RestRoutes.ORDER.WITH_ORDERLINES));
  24. // Then
  25. result.andExpect(status().is(expectedResultHttpCode.value()));
  26. assertEquals(expectedBodyResult, fromJson(result.andReturn().getResponse().getContentAsString(), OrderDto.class));
  27. verify(mockOrderService, times(1)).findByIdWithOrderLines(validOrderId);
  28. }
  1. <details>
  2. <summary>英文:</summary>
  3. There are several ways to solve it:
  4. ## Include individual Json properties comparison ##
  5. import org.springframework.test.web.servlet.MockMvc;
  6. import static org.springframework.http.MediaType.APPLICATION_JSON;
  7. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
  8. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
  9. import static org.hamcrest.core.Is.is;
  10. mockMvc.perform(get(String.format(&quot;/api/v1/product/%s&quot;, Id))
  11. .andExpect(content().contentType(APPLICATION_JSON_VALUE))
  12. .andExpect(jsonPath(&quot;$.id&quot;, is(Id)));
  13. The difference with your example is on **&quot;is import&quot;**.
  14. ----------
  15. ## Deserialize Json response into a class and compare objects ##
  16. This is a more generic and reusable approach.
  17. 1. Use a Json deserialize method to convert that one into an object of a well-known class instance.
  18. 2. Compare expected object with the received one in the test.
  19. You can see a complete example of it in the following
    [1], more specifically in the test:
  20. static Stream&lt;Arguments&gt; findByIdWithOrderLines_validIdTestCases() {
  21. PizzaDto pizzaDto = new PizzaDto((short)1, &quot;Carbonara&quot;, 7.50);
  22. OrderLineDto orderLineDto = new OrderLineDto(10, 1, pizzaDto, (short)2, 15D);
  23. OrderDto dto = new OrderDto(1, &quot;Order 1&quot;, new Date(), asList(orderLineDto));
  24. return Stream.of(
  25. //@formatter:off
  26. // serviceResult, expectedResultHttpCode, expectedBodyResult
  27. Arguments.of( empty(), NOT_FOUND, null ),
  28. Arguments.of( of(dto), OK, dto )
  29. ); //@formatter:on
  30. }
  31. @ParameterizedTest
  32. @SneakyThrows
  33. @WithMockUser(authorities = {Constants.ROLE_ADMIN})
  34. @MethodSource(&quot;findByIdWithOrderLines_validIdTestCases&quot;)
  35. @DisplayName(&quot;findByIdWithOrderLines: when given Id verifies the validations then the suitable Http code is returned&quot;)
  36. public void findByIdWithOrderLines_whenGivenIdVerifiesValidations_thenSuitableHttpCodeIsReturned(Optional&lt;OrderDto&gt; serviceResult,
  37. HttpStatus expectedResultHttpCode, OrderDto expectedBodyResult) {
  38. // Given
  39. Integer validOrderId = 1;
  40. // When
  41. when(mockOrderService.findByIdWithOrderLines(validOrderId)).thenReturn(serviceResult);
  42. ResultActions result = mockMvc.perform(get(RestRoutes.ORDER.ROOT + &quot;/&quot; + validOrderId + RestRoutes.ORDER.WITH_ORDERLINES));
  43. // Then
  44. result.andExpect(status().is(expectedResultHttpCode.value()));
  45. assertEquals(expectedBodyResult, fromJson(result.andReturn().getResponse().getContentAsString(), OrderDto.class));
  46. verify(mockOrderService, times(1)).findByIdWithOrderLines(validOrderId);
  47. }
  48. [1]: https://github.com/doctore/Spring5Microservices/blob/master/order-service/src/test/java/com/order/controller/OrderControllerTest.java
  49. </details>

huangapple
  • 本文由 发表于 2020年8月30日 01:09:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63649712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定