leanmind logo leanmind text logo

Blog

Código Sostenible

Cómo escribir código fácil de mantener mediante valores, principios y técnicas.

Tests de integración con Testcontainers y Spring Boot

Por José Luis Rodríguez Alonso

Para añadir más opciones a nuestra caja de herramientas a la hora de trabajar con Docker y Spring Boot, vamos a ver cómo utilizar Testcontainers a la hora de testear nuestra aplicación.

¿Testcontainers?

Testcontainers es una librería Java que facilita la creación de bases de datos “de usar y tirar” o cualquier otra cosa que se pueda ejecutar en un contenedor Docker.

Uno de los casos de uso más útiles, es tener una base de datos dockerizada sobre la que poder lanzar nuestros tests de integración.

Por suerte, utilizar Testcontainers con Spring Boot no puede ser más sencillo. Aquí tienes un ejemplo utilizando una base de datos MySQL:

Dependencias

Lo primero sería añadir las dependencias según nuestra base de datos, en este caso para MySQL sería:

Con Gradle:

testCompile "org.testcontainers:mysql:1.12.5"

Con Maven:

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>mysql</artifactId>
    <version>1.12.5</version>
    <scope>test</scope>
</dependency>

Existen módulos para PostgreSQL, MariaDB, MSSQL…

Configuración

Ahora, debemos configurar Testcontainers e indicar a Spring que queremos trabajar con nuestra base de datos “dockerizada” en nuestros tests de integración.

Esto lo podemos conseguir dividiendo la configuración del proyecto en dos: por un lado, tendríamos la configuración principal; y, por otro, la configuración para los tests.

Con Spring Boot, esto se puede hacer creando un nuevo archivo application.yaml con un nombre de perfil, por ejemplo: application-local.yaml. En este nuevo archivo configuramos nuestra base de datos dockerizada gracias a Testcontainers.

Por tanto, en nuestro archivo de configuración principal tendríamos algo como esto:

spring:
    datasource:
        url: jdbc:mysql://database:3306/my-app

Y en nuestro application-local.yaml sobrescribimos la url así:

spring:
    datasource:
        url: jdbc:tc:mysql:8.0:///my-app?TC_INITSCRIPT=database/create_tables.sql

Como ves, la configuración se hace directamente en la url de conexión. En este caso, estamos indicando al driver de Testcontainers (tc) que queremos:

Y eso sería todo. A partir de esa información, Testcontainers es capaz de descargar la imagen de MySQL 8.0 e iniciarla, encargándose también de detener la ejecución de nuestro código hasta que esté todo listo. También se encarga de limpiar todo al acabar los tests.

Ejemplo de uso

El último paso sería hacer un test de integración para probar que todo funciona como esperamos. Este test lo tenemos que ejecutar con nuestro perfil “local” activado.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@ActiveProfiles("local")
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class ProductHandlerTest {
    private final NamedParameterJdbcTemplate jdbcTemplate;
    private final WebTestClient webTestClient;

    @Autowired
    ProductHandlerTest(
            NamedParameterJdbcTemplate jdbcTemplate,
            WebTestClient webTestClient
    ) {
        this.jdbcTemplate = jdbcTemplate;
        this.webTestClient = webTestClient;
    }

    @Test
    void returnsExistingProducts() {
        executeSql(jdbcTemplate, "database/create_products.sql");

        webTestClient
                .get().uri("/products/1")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                .expectStatus().isOk()
                .expectBody()
                .jsonPath("$.name").isEqualTo("Almogrote");
    }
}

Al tener el perfil local activado, Spring carga nuestro archivo de configuración e invoca al driver de Testcontainers que inicializa la base de datos. A partir de ahí, el jdbcTemplate que inyectamos al test nos permite insertar datos en nuestro MySQL dockerizado.

Conclusión

it's magic!

Testcontainers puede ser una herramienta útil para tener tests de integración con bases de datos reales sin tener que preocuparte de configurar Docker y demás. Con solo dos líneas de código (dependencia + url de conexión) ya lo tienes todo para empezar a trastear.

También tiene soporte para Selenium y algunas otras cosas que pueden resultar útiles.

Nota: En las pruebas he utilizado Spring Boot 2.3, en versiones anteriores es necesario indicar el driver de Testcontainers en nuestro archivo de configuración local:

    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
Publicado el 17/02/2020 por
José Luis image

José Luis Rodríguez Alonso

¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.

Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?

Impulsamos el crecimiento profesional de tu equipo de developers