使用MockMVC在Junit5春季启动中jsonPath cast问题

时间:2020-08-29 17:09:11

标签: java spring junit junit5 mockmvc

我有以下测试用例,导入为

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

获取错误信息

enter image description here

如果投射对象,则会收到投射错误消息。

enter image description here

1 个答案:

答案 0 :(得分:1)

有几种解决方法:

包括单个Json属性比较

import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.hamcrest.core.Is.is;

mockMvc.perform(get(String.format("/api/v1/product/%s", Id))
       .andExpect(content().contentType(APPLICATION_JSON_VALUE))
       .andExpect(jsonPath("$.id", is(Id)));

与您的示例的区别在于“正在导入”


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

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

  1. 使用Json反序列化方法将其转换为众所周知的类实例的对象。
  2. 将预期对象与测试中收到的对象进行比较。

您可以在以下link中看到它的完整示例,更具体地说,是在测试中:

static Stream<Arguments> findByIdWithOrderLines_validIdTestCases() {
  PizzaDto pizzaDto = new PizzaDto((short)1, "Carbonara", 7.50);
  OrderLineDto orderLineDto = new OrderLineDto(10, 1, pizzaDto, (short)2, 15D);
  OrderDto dto = new OrderDto(1, "Order 1", new Date(), asList(orderLineDto));
  return Stream.of(
      //@formatter:off
      //            serviceResult,   expectedResultHttpCode,   expectedBodyResult
      Arguments.of( empty(),         NOT_FOUND,                null ),
      Arguments.of( of(dto),         OK,                       dto )
  ); //@formatter:on
}

@ParameterizedTest
@SneakyThrows
@WithMockUser(authorities = {Constants.ROLE_ADMIN})
@MethodSource("findByIdWithOrderLines_validIdTestCases")
@DisplayName("findByIdWithOrderLines: when given Id verifies the validations then the suitable Http code is returned")
public void findByIdWithOrderLines_whenGivenIdVerifiesValidations_thenSuitableHttpCodeIsReturned(Optional<OrderDto> serviceResult,
                                      HttpStatus expectedResultHttpCode, OrderDto expectedBodyResult) {
    // Given
    Integer validOrderId = 1;

    // When
    when(mockOrderService.findByIdWithOrderLines(validOrderId)).thenReturn(serviceResult);

    ResultActions result = mockMvc.perform(get(RestRoutes.ORDER.ROOT + "/" + validOrderId + RestRoutes.ORDER.WITH_ORDERLINES));

    // Then
    result.andExpect(status().is(expectedResultHttpCode.value()));
    assertEquals(expectedBodyResult, fromJson(result.andReturn().getResponse().getContentAsString(), OrderDto.class));
    verify(mockOrderService, times(1)).findByIdWithOrderLines(validOrderId);
}
相关问题