Introducción: Por qué las pruebas en Kotlin son un superpoder, no una obligación aburrida
\n\nImagina: escribiste una aplicación en Kotlin. Funciona. Eres feliz. Pero pasa una semana, agregas una nueva funcionalidad y de repente se rompe algo que ya funcionaba. ¿Te suena familiar? Si no es así, o eres un genio o nunca has escrito código sin pruebas. Las pruebas en Kotlin no son solo una casilla que marcar en la lista de tareas del desarrollador. Son tu "escudo" personal contra errores, una forma de dormir tranquilo después del despliegue y una herramienta que hace que el código sea más limpio y comprensible.
\n\nEn este artículo, te mostraré por dónde empezar con las pruebas en Kotlin como desarrollador principiante. Analizaremos ejemplos reales, bibliotecas populares y trucos que te ahorrarán horas de depuración. Aprenderás a escribir pruebas unitarias, simular dependencias y probar corrutinas. ¡Vamos allá!
\n\nPaso 1: Configuración del entorno — los primeros 5 minutos
\n\nAntes de escribir tu primera prueba, necesitas agregar las dependencias. Si usas Gradle (y probablemente lo hagas), añade las siguientes líneas a tu archivo build.gradle.kts:
// build.gradle.kts\ndependencies {\n // JUnit 5 — la base de las pruebas unitarias\n testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")\n \n // MockK — la mejor biblioteca para mocks en Kotlin\n testImplementation("io.mockk:mockk:1.13.8")\n \n // AssertJ — aserciones hermosas y legibles\n testImplementation("org.assertj:assertj-core:3.24.2")\n \n // Para probar corrutinas\n testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")\n}\n\ntasks.test {\n useJUnitPlatform()\n}\n\n¡Listo! Ahora tienes todo lo necesario para escribir pruebas. Ten en cuenta: estamos usando JUnit 5 (no la versión 4) — es el estándar moderno que funciona muy bien con Kotlin. MockK no se eligió al azar: entiende la seguridad de nulos (null-safety), las funciones de extensión y otras características de Kotlin con las que Mockito tiene dificultades.
\n\nPaso 2: Tu primera prueba unitaria en Kotlin
\n\nEscribamos una clase simple y probémosla. Supongamos que tenemos una calculadora de descuentos:
\n\n// DiscountCalculator.kt\nclass DiscountCalculator {\n fun calculateDiscount(price: Double, discountPercent: Int): Double {\n require(price >= 0) { "El precio no puede ser negativo" }\n require(discountPercent in 0..100) { "El descuento debe estar entre 0 y 100" }\n return price * (100 - discountPercent) / 100.0\n }\n}\n\nAhora escribamos la prueba. Crea un archivo DiscountCalculatorTest.kt en la carpeta src/test/kotlin:
import org.junit.jupiter.api.Test\nimport org.junit.jupiter.api.assertThrows\nimport org.assertj.core.api.Assertions.assertThat\n\nclass DiscountCalculatorTest {\n \n private val calculator = DiscountCalculator()\n \n @Test\n fun `debería calcular correctamente un descuento del 20%`() {\n val result = calculator.calculateDiscount(1000.0, 20)\n assertThat(result).isEqualTo(800.0)\n }\n \n @Test\n fun `debería lanzar una excepción con precio negativo`() {\n assertThrows<IllegalArgumentException> {\n calculator.calculateDiscount(-100.0, 10)\n }\n }\n \n @Test\n fun `debería devolver el precio completo con descuento del 0%`() {\n val result = calculator.calculateDiscount(500.0, 0)\n assertThat(result).isEqualTo(500.0)\n }\n}\n\nObserva el estilo: usamos comillas invertidas para los nombres de las pruebas en español (Kotlin lo permite). Esto hace que las pruebas sean legibles incluso para un colega no técnico. AssertJ proporciona una interfaz fluida: assertThat(result).isEqualTo(800.0) — se lee como una oración en inglés.
Paso 3: Mocks con MockK — cuando probamos dependencias
\n\nEn aplicaciones reales, las clases rara vez viven solas. Se comunican con bases de datos, APIs u otros servicios. Para no depender de sistemas externos, usamos mocks. Supongamos que tenemos un servicio de