Проблема с Mockito и JpaRepository

У меня есть проект загрузки Spring, который я перехожу на Spring boot 2. Некоторые из моих тестов, которые работали с предыдущей версией, не работают с новой версией.

Проблема легко воспроизвести.

Создаю 2 Контроллера. Во-первых, я ввожу услугу. Во втором я ввожу JpaRepository.

Теперь я создаю UnitTests для этого контроллера. Для второго контроллера я имитирую репозиторий. Все нормально работает. Для первого Контроллера я издеваюсь над Сервисом. Тест не пройден. Кажется, что он пытается внедрить репозиторий, хотя он не используется в этом контроллере.

Я создаю очень простой проект, чтобы воспроизвести это поведение: https://github.com/YLombardi/mockito-spring-jpa-issue

Это мой тест неправильный или ошибка?

0
0
584
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мне удалось воспроизвести проблему из предоставленного вами 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"));
    }

Итак, мне нужно издеваться над JpaRepo в каждом тестовом классе? Даже если он не используется в контроллере. Это кажется странным. В предыдущей весенней версии нам нужно было имитировать только тот компонент, который был внедрен в тестируемый класс.

YLombardi 14.03.2018 08:59

По умолчанию MockMvc загружается со всем контекстом. Если вы просто хотите иметь контекст для одного контроллера, создайте автономный контекст с помощью MockMvcBuilders.standaloneSetup....

Yogesh Badke 14.03.2018 09:01

«Нам нужно было смоделировать только тот компонент, который был внедрен в тестируемый класс.» - Верно при запуске теста с MockitoJunitRunner.

Yogesh Badke 14.03.2018 09:04

Спасибо, я понял свою ошибку. Новая аннотация @WebMvcTest не отменяет необходимости настраивать MockMvcBuilders.standaloneSetup (controllerA) .build ();

YLombardi 14.03.2018 09:32

Другие вопросы по теме