У меня есть проект загрузки Spring, который я перехожу на Spring boot 2. Некоторые из моих тестов, которые работали с предыдущей версией, не работают с новой версией.
Проблема легко воспроизвести.
Создаю 2 Контроллера. Во-первых, я ввожу услугу. Во втором я ввожу JpaRepository.
Теперь я создаю UnitTests для этого контроллера. Для второго контроллера я имитирую репозиторий. Все нормально работает. Для первого Контроллера я издеваюсь над Сервисом. Тест не пройден. Кажется, что он пытается внедрить репозиторий, хотя он не используется в этом контроллере.
Я создаю очень простой проект, чтобы воспроизвести это поведение: https://github.com/YLombardi/mockito-spring-jpa-issue
Это мой тест неправильный или ошибка?
Мне удалось воспроизвести проблему из предоставленного вами URL-адреса репо. Если вы заметили исключение при запуске ControllerAUnitTests, появится сообщение
...UnsatisfiedDependencyException: Error creating bean with name 'controllerB'...
Итак, зачем Spring пытаться загрузить bean-компонент controllerB, когда вы выполняете тесты для ControllerA?
Это потому, что вы используете SpringRunner и mockMvc по умолчанию. Он загружает весь контекст Spring, что означает, что он будет создавать bean-компоненты каждого компонента, включая controllerB.
Чтобы создать компонент controllerB, вам нужен экземпляр JpaRepo. Итак, точно так же, как вы создали фиктивный bean-компонент ServiceA в ControllerAUnitTests, вам также необходимо создать фиктивный bean-компонент для JpaRepo.
@MockBean
private ServiceA serviceA;
// NOTE THIS BLOCK
@MockBean
private JpaRepo jpaRepo;
@Test
public void test() throws Exception {
doReturn("a").when(serviceA).getAString();
mockMvc.perform(get("/a"))
.andDo(print())
.andExpect(status().isOk())
// Test now runs but assert fails below, that you need to fix.
.andExpect(view().name("aview"))
.andExpect(content().string("a"));
}
По умолчанию MockMvc загружается со всем контекстом. Если вы просто хотите иметь контекст для одного контроллера, создайте автономный контекст с помощью MockMvcBuilders.standaloneSetup....
«Нам нужно было смоделировать только тот компонент, который был внедрен в тестируемый класс.» - Верно при запуске теста с MockitoJunitRunner.
Спасибо, я понял свою ошибку. Новая аннотация @WebMvcTest не отменяет необходимости настраивать MockMvcBuilders.standaloneSetup (controllerA) .build ();
Итак, мне нужно издеваться над JpaRepo в каждом тестовом классе? Даже если он не используется в контроллере. Это кажется странным. В предыдущей весенней версии нам нужно было имитировать только тот компонент, который был внедрен в тестируемый класс.