Интеграционное тестирование в SpringBoot с TestContainers-стартером

от автора

Перевод статьи подготовлен в преддверии старта курса «Разработчик на Spring Framework».


Одна из причин популярности Spring и Spring Boot — это хорошая поддержка тестирования. Можно писать как юнит-тесты с Mockito без использования функциональности Spring’а, так и интеграционные с инициализацией Spring-контекста.

Для интеграционных тестов может потребоваться взаимодействие с внешними сервисами, такими как реляционные базы данных, NoSQL-базы данных, Kafka и другими. При тестировании удобно разворачивать эти сервисы в Docker-контейнерах.

Testcontainers

Из документации Testcontainers:

TestContainers — это Java-библиотека, которая поддерживает JUnit-тесты, предоставляя легкие, временные экземпляры для популярных баз данных, веб-браузеров с Selenium и всего остального, что может работать в Docker-контейнере.

С помощью Testcontainers запустить Singleton Docker-контейнер можно следующим образом:

@SpringBootTest @ContextConfiguration(initializers = {UserServiceIntegrationTest.Initializer.class}) class UserServiceIntegrationTest {     private static PostgreSQLContainer sqlContainer;          static {         sqlContainer = new PostgreSQLContainer("postgres:10.7")                 .withDatabaseName("integration-tests-db")                 .withUsername("sa")                 .withPassword("sa");         sqlContainer.start();     }      static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {         public void initialize(ConfigurableApplicationContext configurableApplicationContext) {             TestPropertyValues.of(               "spring.datasource.url=" + sqlContainer.getJdbcUrl(),               "spring.datasource.username=" + sqlContainer.getUsername(),               "spring.datasource.password=" + sqlContainer.getPassword()             ).applyTo(configurableApplicationContext.getEnvironment());         }     }      @Autowired     private UserService userService;          @Test     void shouldGetAllUsers() {         // test userService.getAllUsers()     }     }

Так как такое используется довольно часто, то для упрощения жизни сообществом был создан стартер — Testcontainers Spring Boot Starter.

Testcontainers SpringBoot Starter

Testcontainers—стартер зависит от spring-cloud-starter. Если в вашем приложении не используются SpringCloud-стартеры, то необходимо добавить spring-cloud-starter как test-зависимость.

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter</artifactId>     <scope>test</scope> </dependency>

И также добавить библиотеку для базы данных. Например, если вы хотите использовать Postgresql:

<dependency>     <groupId>com.playtika.testcontainers</groupId>     <artifactId>embedded-postgresql</artifactId>     <scope>test</scope> </dependency>

При добавлении embedded-postgresql в окружении будут доступны следующие свойства:

embedded.postgresql.port embedded.postgresql.host embedded.postgresql.schema embedded.postgresql.user embedded.postgresql.password

Их можно использовать для настройки источника данных (datasource).

Как правило, Docker-контейнеры используются только для интеграционных тестов, но не для юнит-тестов. С помощью профилей мы можем отключить их по умолчанию и включить только для интеграционных тестов.

src/test/resources/bootstrap.properties

embedded.postgresql.enabled=false

src/test/resources/bootstrap-integration-test.properties

embedded.postgresql.enabled=true spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://${embedded.postgresql.host}:${embedded.postgresql.port}/${embedded.postgresql.schema} spring.datasource.username=${embedded.postgresql.user} spring.datasource.password=${embedded.postgresql.password}

Теперь можно запускать интеграционные тесты с профилем integration-test с помощью @ActiveProfiles:

@SpringBootTest @ActiveProfiles("integration-test") class UserServiceIntegrationTest {          @Autowired     private UserService userService;          @Test     void shouldGetAllUsers() {         // test userService.getAllUsers()     }     }

Указать конкретную версию docker-образа можно следующим образом:

src/test/resources/bootstrap-integration-test.properties

embedded.postgresql.dockerImage=postgres:10.7 embedded.postgresql.enabled=true

Testcontainers-стартер уже обеспечивает поддержку наиболее популярных контейнеров, таких как Postgresql, MariaDB, MongoDB, Redis, RabbitMQ, Kafka, Elasticsearch и других.
На удивление, на данный момент нет прямой поддержки MySQL. Хотя для этого есть простое обходное решение, описанное здесь


Рефакторинг кода приложений на Spring


ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/514270/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *