Pruebas de integración de Kotlin con Docker: de la A a la Z
\n\nEn el desarrollo moderno con Kotlin, las pruebas de integración con Docker se han convertido en el estándar de facto. La contenerización permite crear entornos de prueba aislados y reproducibles que se acercan al máximo al entorno de producción. En este artículo, analizaremos el proceso completo de configuración y escritura de pruebas de integración para aplicaciones Kotlin con Docker y la biblioteca Testcontainers.
\n\n¿Por qué es importante Docker para las pruebas de integración de Kotlin?
\n\nLas pruebas de integración tradicionales a menudo sufren problemas de entorno: diferentes versiones de bases de datos, incompatibilidad de controladores, pruebas "flotantes" debido a procesos en segundo plano. Docker resuelve estos problemas proporcionando:
\n\n- \n
- Aislamiento: cada prueba se ejecuta en un contenedor limpio \n
- Reproducibilidad: el mismo entorno en cualquier máquina \n
- Escalabilidad: posibilidad de probar arquitecturas de microservicios complejas \n
- Velocidad: inicio y detención rápidos de contenedores \n
Configuración del proyecto Kotlin para pruebas de integración con Docker
\n\nPara empezar, agreguemos las dependencias necesarias en build.gradle.kts:
dependencies {\n // Testcontainers\n testImplementation("org.testcontainers:testcontainers:1.19.3")\n testImplementation("org.testcontainers:postgresql:1.19.3")\n testImplementation("org.testcontainers:kafka:1.19.3")\n testImplementation("org.testcontainers:junit-jupiter:1.19.3")\n \n // Base de datos\n testImplementation("org.postgresql:postgresql:42.7.1")\n \n // JUnit 5\n testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")\n \n // Para aplicaciones Spring Boot\n testImplementation("org.springframework.boot:spring-boot-starter-test:3.2.1")\n testImplementation("org.springframework.boot:spring-boot-testcontainers:3.2.1")\n}\n\nEjemplo básico: pruebas con PostgreSQL
\n\nConsideremos un ejemplo simple: probar un repositorio que trabaja con PostgreSQL. Creemos una prueba de integración usando Testcontainers:
\n\nimport org.junit.jupiter.api.Test\nimport org.testcontainers.containers.PostgreSQLContainer\nimport org.testcontainers.junit.jupiter.Container\nimport org.testcontainers.junit.jupiter.Testcontainers\nimport javax.sql.DataSource\n\n@Testcontainers\nclass UserRepositoryIntegrationTest {\n\n companion object {\n @Container\n val postgres = PostgreSQLContainer<Nothing>("postgres:15-alpine").apply {\n withDatabaseName("testdb")\n withUsername("test")\n withPassword("test")\n }\n }\n\n @Test\n fun `should save and find user`() {\n val dataSource = createDataSource(postgres)\n val repository = UserRepository(dataSource)\n \n val user = User(id = null, name = "Iván Petrov", email = "ivan@example.com")\n val savedUser = repository.save(user)\n \n val foundUser = repository.findById(savedUser.id!!)\n assert(foundUser != null)\n assert(foundUser?.name == "Iván Petrov")\n }\n\n private fun createDataSource(container: PostgreSQLContainer<*>): DataSource {\n val config = HikariConfig().apply {\n jdbcUrl = container.jdbcUrl\n username = container.username\n password = container.password\n driverClassName = container.driverClassName\n }\n return HikariDataSource(config)\n }\n}\n\nPruebas de microservicios con Kafka y Docker Compose
\n\nPara escenarios más complejos, donde se requieren múltiples servicios, use Docker Compose a través de Testcontainers:
\n\nimport org.testcontainers.containers.DockerComposeContainer\nimport org.testcontainers.containers.wait.strategy.Wait\nimport java.io.File\n\nclass OrderService