Pruebas de integración en SpringBoot con TestContainers starter

La traducción del artículo se preparó antes del inicio del curso "Desarrollador en Spring Framework" .








Una de las razones por las que Spring y Spring Boot son tan populares es su buen soporte de prueba . Puede escribir tanto pruebas unitarias con Mockito sin usar la funcionalidad Spring como pruebas de integración con la inicialización del contexto Spring.



Las pruebas de integración pueden requerir la interacción con servicios externos como bases de datos relacionales, bases de datos NoSQL, Kafka y otros. Al realizar pruebas, es conveniente implementar estos servicios en contenedores de Docker.



Contenedores de prueba



De la documentación de Testcontainers:



TestContainers es una biblioteca Java que admite pruebas JUnit al proporcionar instancias ligeras y transitorias para bases de datos populares, navegadores web con Selenium y cualquier otra cosa que pueda ejecutarse en un contenedor Docker.




Con Testcontainers, puede iniciar un contenedor Singleton Docker de la siguiente manera:



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

}


Dado que esto se usa con bastante frecuencia, la comunidad creó un iniciador para simplificar la vida de la comunidad: Testcontainers Spring Boot Starter .



Testcontainers SpringBoot Starter



Contenedores de prueba: el iniciador depende del iniciador de nubes de primavera . Si su aplicación no usa arrancadores SpringCloud, entonces necesita agregar spring-cloud-starter como dependencia de prueba.



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


Y también agregue la biblioteca para la base de datos. Por ejemplo, si desea utilizar Postgresql:



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


Cuando se agregue embedded-postgresqlal entorno, estarán disponibles las siguientes propiedades:



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


Se pueden utilizar para configurar una fuente de datos.



Normalmente, los contenedores de Docker solo se utilizan para pruebas de integración, no para pruebas unitarias. Con la ayuda de los perfiles, podemos deshabilitarlos por defecto y habilitarlos solo para pruebas de integración.



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}


Ahora puede ejecutar pruebas de integración con el perfil de prueba de integración usando @ActiveProfiles:



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

}


Puede especificar una versión específica de la imagen de la ventana acoplable de la siguiente manera:



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



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




El iniciador de testcontainers ya proporciona soporte para los contenedores más populares como Postgresql, MariaDB, MongoDB, Redis, RabbitMQ, Kafka, Elasticsearch y otros.

Sorprendentemente, actualmente no hay soporte directo para MySQL. Aunque hay una solución simple para esto, como se describe aquí






Refactorización del código de la aplicación en Spring







All Articles