Integrationstests in SpringBoot mit TestContainers Starter

Die Übersetzung des Artikels wurde im Vorfeld des Kurses "Developer on the Spring Framework" vorbereitet .








Einer der Gründe, warum Spring und Spring Boot so beliebt sind, ist ihre gute Testunterstützung . Sie können sowohl Komponententests mit Mockito ohne Verwendung der Spring-Funktionalität als auch Integrationstests mit der Initialisierung des Spring-Kontexts schreiben .



Integrationstests erfordern möglicherweise die Interaktion mit externen Diensten wie relationalen Datenbanken, NoSQL-Datenbanken, Kafka und anderen. Beim Testen ist es zweckmäßig, diese Dienste in Docker-Containern bereitzustellen.



Testcontainer



Aus der Dokumentation zu Testcontainers:



TestContainers ist eine Java-Bibliothek, die JUnit-Tests unterstützt, indem sie einfache, vorübergehende Instanzen für gängige Datenbanken, Webbrowser mit Selenium und alles andere bereitstellt, was in einem Docker-Container ausgeführt werden kann.




Mit Testcontainern können Sie einen Singleton Docker-Container wie folgt starten :



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

}


Da dies häufig verwendet wird, wurde von der Community ein Starter erstellt, um das Leben der Community zu vereinfachen - Testcontainers Spring Boot Starter .



Testcontainer SpringBoot Starter



Testcontainers - Der Starter ist abhängig von der feder Cloud-Starter . Wenn Ihre Anwendung keine SpringCloud-Starter verwendet, müssen Sie Spring-Cloud-Starter als Testabhängigkeit hinzufügen .



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


Fügen Sie außerdem die Bibliothek für die Datenbank hinzu. Wenn Sie beispielsweise Postgresql verwenden möchten:



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


Beim Hinzufügen embedded-postgresqlzur Umgebung stehen folgende Eigenschaften zur Verfügung:



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


Sie können zum Einrichten einer Datenquelle verwendet werden.



In der Regel werden Docker-Container nur für Integrationstests verwendet, nicht für Komponententests. Mithilfe von Profilen können wir sie standardmäßig deaktivieren und nur für Integrationstests aktivieren.



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}


Jetzt können Sie Integrationstests mit dem Integrationstestprofil ausführen, indem Sie @ActiveProfiles:



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

}


Sie können eine bestimmte Version des Docker-Images wie folgt angeben:



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



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




Der Starter von Testcontainers bietet bereits Unterstützung für die beliebtesten Container wie Postgresql, MariaDB, MongoDB, Redis, RabbitMQ, Kafka, Elasticsearch und andere.

Überraschenderweise gibt es derzeit keine direkte Unterstützung für MySQL. Es gibt zwar eine einfache Problemumgehung dafür, wie hier beschrieben






Refactoring des Anwendungscodes im Frühjahr







All Articles