Spring Boot: тестирование, моки компонентов и компоненты-шпионы

При запуске тестов иногда необходимо смоделировать определенные компоненты в контексте вашего приложения. Например, у вас может быть фасад поверх некоторого удаленного сервиса, который недоступен во время разработки. Моки могут быть полезны, если вы хотите смоделировать сбои, которые трудно вызвать в реальной среде.

Spring Boot включает аннотацию @MockBean, которую можно использовать для определения Mockito mock для компонента внутри вашего ApplicationContext. Вы можете использовать аннотацию для добавления новых bean-компонентов или замены одного существующего определения bean-компонента. Аннотацию можно использовать непосредственно в тестовых классах, в полях вашего теста или в классах и полях @Configuration. При использовании в поле, экземпляр созданного мока также внедряется. Mock компоненты автоматически сбрасываются после каждого метода тестирования.

Если в вашем тесте используется одна из аннотаций теста Spring Boot (например, @SpringBootTest), эта функция автоматически включается. Чтобы использовать эту функцию с другим расположением, слушатель должен быть явно добавлен, как показано в следующем примере:

@TestExecutionListeners(MockitoTestExecutionListener.class)

В следующем примере заменяется существующий компонент RemoteService на фиктивную (mock) реализацию:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@SpringBootTest
class MyTests {

    @MockBean
    private RemoteService remoteService;

    @Autowired
    private Reverser reverser;

    @Test
    void exampleTest() {
        // RemoteService был внедрен в bean-компонент reverser
        given(this.remoteService.someCall()).willReturn("mock");
        String reverse = reverser.reverseSomeCall();
        assertThat(reverse).isEqualTo("kcom");
    }

}

@MockBean нельзя использовать для проверки поведения компонента, который используется во время обновления контекста приложения. Ко времени выполнения теста обновление контекста приложения завершено, и уже слишком поздно настраивать mock поведение. Рекомендуется использовать метод @Bean для создания и настройки mock в этой ситуации.

Кроме того, вы можете использовать @SpyBean, чтобы обернуть любой существующий компонент шпионом Mockito (Mockito spy).

Прокси-серверы CGLib, такие как созданные для bean-компонентов, объявляют прокси-методы как final. Это мешает Mockito работать правильно, так как он не может создавать mock или spy на final методы в конфигурации по умолчанию. Если вы хотите создавать mock или spy для такого компонента, настройте Mockito на использование встроенного создателя mock, добавив org.mockito:mockito-inline к тестовым зависимостям вашего приложения. Это позволяет Mockito создавать mock и spy для final методов.

В то время как среда тестирования Spring кэширует контексты приложения между тестами и повторно использует контекст для тестов, использующих одну и ту же конфигурацию, использование @MockBean или @SpyBean влияет на ключ кэша, что, скорее всего, увеличит количество контекстов.

Если вы используете @SpyBean для слежения за компонентом с помощью методов @Cacheable, которые ссылаются на параметры по имени, ваше приложение должно быть скомпилировано с параметром -parameters. Это гарантирует, что имена параметров будут доступны для инфраструктуры кэширования после отслеживания компонента.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки