Test d'intégration dans SpringBoot avec le démarreur TestContainers

La traduction de l'article a été préparée en prévision du début du cours "Developer on the Spring Framework" .








L'une des raisons de la popularité de Spring et Spring Boot est leur bon support de test . Vous pouvez écrire à la fois des tests unitaires avec Mockito sans utiliser la fonctionnalité de Spring et des tests d' intégration avec l'initialisation du contexte Spring.



Les tests d'intégration peuvent nécessiter une interaction avec des services externes tels que des bases de données relationnelles, des bases de données NoSQL, Kafka et autres. Lors des tests, il est pratique de déployer ces services dans des conteneurs Docker.



Conteneurs de test



De la documentation Testcontainers:



TestContainers est une bibliothèque Java qui prend en charge les tests JUnit en fournissant des instances légères et transitoires pour les bases de données populaires, les navigateurs Web avec Selenium et tout ce qui peut s'exécuter dans un conteneur Docker.




À l'aide de Testcontainers, vous pouvez lancer un conteneur Singleton Docker comme suit:



@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()
    }   

}


Comme cela est utilisé assez souvent, un démarreur a été créé par la communauté pour simplifier la vie de la communauté - Testcontainers Spring Boot Starter .



Testcontainers SpringBoot Starter



Testcontainers - Le démarreur dépend du ressort-nuage-démarreur . Si votre application n'utilise pas de démarreurs SpringCloud, vous devez ajouter spring-cloud-starter comme dépendance de test.



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


Et ajoutez également la bibliothèque pour la base de données. Par exemple, si vous souhaitez utiliser Postgresql:



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


Une fois ajoutées embedded-postgresqlà l'environnement, les propriétés suivantes seront disponibles:



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


Ils peuvent être utilisés pour configurer une source de données.



En règle générale, les conteneurs Docker ne sont utilisés que pour les tests d'intégration, pas pour les tests unitaires. À l'aide de profils, nous pouvons les désactiver par défaut et les activer uniquement pour les tests d'intégration.



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}


Vous pouvez maintenant exécuter des tests d'intégration avec le profil de test d'intégration en utilisant @ActiveProfiles:



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

}


Vous pouvez spécifier une version spécifique de l'image du docker comme suit:



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



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




Le démarreur testcontainers prend déjà en charge les conteneurs les plus populaires tels que Postgresql, MariaDB, MongoDB, Redis, RabbitMQ, Kafka, Elasticsearch, etc.

Étonnamment, il n'y a actuellement aucun support direct pour MySQL. Bien qu'il existe une solution de contournement simple pour cela, comme décrit ici






Refactorisation du code d'application au printemps







All Articles