Сопоставьте LocalDateTime с помощью Hamcrest в MVC Test - PullRequest
0 голосов
/ 05 августа 2020

Я изо всех сил пытаюсь реализовать тест контроллера Spring MVC для поля LocalDateTime с использованием Mockito и Hamcrest.

@WebMvcTest(controllers = FooController.class)
class FooControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private FooService fooService;

  @Test
  void testController() throws Exception {
    Foo foo = new Foo(LocalDateTime.now());
    List<Foo> allFoos = Arrays.asList(foo);

    given(fooService.getAllFoos()).willReturn(allFoos);

    mockMvc.perform(get("/foos").contentType(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$", hasSize(1)))
        .andExpect(jsonPath("$[0].timeOfUpdate", equalTo(foo.getTimeOfUpdate()), LocalDateTime.class));
  }
}

Контроллер возвращает JSON сериализованный объект Foo, который выглядит как что:

@Getter
@Setter
@AllArgsConstructor
class Foo {
  private LocalDateTime timeOfUpdate;
}

Ответ JSON выглядит так:

[
  {
     "timeOfUpdate":"2020-08-05T18:40:30.7416748"
  }
]

Однако, когда я пытаюсь сопоставить поле timeOfUpdate с equalTo, я получаю следующее ошибка:

java.lang.AssertionError: JSON path "$[0].timeOfUpdate"
Expected: <2020-08-05T18:40:30.741674800>
     but: was "2020-08-05T18:40:30.7416748"

Итак, похоже, это ошибка точности, но я не знаю, как ее решить.

Обновление:

Я изменил Matcher на следующее:

andExpect(jsonPath("$[0].timeOfUpdate").value(foo.getTimeOfUpdate()));

Теперь кажется, что типы правильные, но утверждение по-прежнему не работает:

java.lang.AssertionError: JSON path "$[0].timeOfUpdate" expected:<2020-08-05T19:19:05.739893500> but was:<2020-08-05T19:19:05.7398935>
Expected :2020-08-05T19:19:05.739893500
Actual   :2020-08-05T19:19:05.7398935

Обновление 2

Вот один обходной путь, чтобы тесты стали зелеными:

.andExpect(jsonPath("$[0].statusRecord.timeOfUpdate", is(person.getStatusRecord().getTimeOfUpdate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'hh:mm:ss")))));
@Getter
@Setter
@AllArgsConstructor
class Foo {
  @JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd'T'hh:mm:ss")
  private LocalDateTime timeOfUpdate;
}

1 Ответ

0 голосов
/ 09 августа 2020

Вам просто нужно использовать toString() для .value(foo.getTimeOfUpdate().toString()), поскольку jsonPath("$[0].timeOfUpdate" - это json строка. Я тоже столкнулся с той же проблемой.

Вот ваш тестовый класс выглядит после изменения.

@WebMvcTest(controllers = FooController.class)
class FooControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private FooService fooService;

  @Test
  void testController() throws Exception {
    Foo foo = new Foo(LocalDateTime.now());
    List<Foo> allFoos = Arrays.asList(foo);

    given(fooService.getAllFoos()).willReturn(allFoos);

    mockMvc.perform(get("/foos").contentType(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$", hasSize(1)))
        .andExpect(jsonPath("$[0].timeOfUpdate").value(foo.getTimeOfUpdate().toString()));
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...