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