Por supuesto, Kotlin también nos permite hacer test unitarios sobre el código Java de forma muy sencilla, y muy parecida a lo que estamos acostumbrados en Java.
Hay alguna pequeña cosa que se complica cuando utilizamos librerías como Mockito, pero veremos algunos trucos para que sea más sencillo.
Si quieres aprender cuál es la situación de Kotlin en el mercado, por qué debes aprenderlo y los primeros pasos para que veas lo fácil que es, he preparado un training gratuito de hora y media al que puedes unirte haciendo click aquí.
Tests unitarios en Kotlin
Aunque el tema de lo que es un test unitario siempre genera controversia, no voy a entrar aquí en detalles sobre lo que es o no es un test unitario.
Para nuestro ejemplo en particular, es suficiente pensar que un test unitario es aquel test que no necesita un dispositivo para ejecutarse. El IDE será capaz de ejecutarlos y mostrar un resultado, identificando cuáles se ejecutaron y cuáles fallaron.
Configura Gradle
Necesitas añadir jUnit a tus dependencias. Es posible que cuando creaste el proyecto ya se incluyera por defecto. También vamos a añadir Mockito, pues lo utilizaremos después:
testCompile "junit:junit:4.12" testCompile "org.mockito:mockito-core:1.10.19"
Crea tu primer test
En la carpeta app/src/test
(créala si no existe), puedes crear una nueva clase llama MyTest
, que tenga la siguiente forma:
class MyTest { @Test fun testsWork() { assertTrue(true) } }
Como ves, es muy similar a lo que estás acostumbrado en Java, con la nomenclatura típica de Kotlin.
Cómo usar Mockito
Mockito en Kotlin se puede usar como cualquier otra librería, si bien es cierto que te vas a encontrar con ciertas complicaciones que vas a necesitar solventar.
Aquí tienes un ejemplo extraído del libro:
@Test fun emptyDatabaseReturnsServerValue() { val db = Mockito.mock(ForecastDataSource::class.java) val server = Mockito.mock(ForecastDataSource::class.java) `when`(server.requestForecastByZipCode(any(Long::class.java), any(Long::class.java))) .then { ForecastList(0, "city", "country", listOf()) } val provider = ForecastProvider(listOf(db, server)) assertNotNull(provider.requestByZipCode(0, 0)) }
Como ves, todo es muy similar. Puedes crear tus mocks y utilizarlos sin problemas a lo largo del código. Aunque aquí no lo estoy haciendo, también podrías usar MockitoJUnitRunner
y anotaciones.
La palabra when
es una palabra reservada en Kotlin, y por eso es necesario usarla con comillas invertidas, o incluso podrías renombrar el import
y darle el nombre que quieras:
import org.mockito.Mockito.`when` as _when
El problema surge cuando se intentan mockear tipos que no permiten valores nulos. Mockito por defecto lo que hace es dar valores nulos a los objetos que mockea, con lo que tarde o temprando surgirán problemas.
Un pequeño truco es usar alguna librería como mockito-kotlin, que en vez de usar nulos, dará valores por defecto específicos a cada tipo, solventando ese problema. Además, da otras funciones que aprovechan la potencia de Kotlin para hacer las cosas más sencillas.
Otro problema es que, por defecto, todas las clases y funciones en Kotlin son cerradas, lo que quiere decir que no se pueden extender. Esto es un problema para Mockito, pues no es capaz de mockearlas.
La única solución hoy en día es crear interfaces para todo, o hacer open
todo lo que queramos mockear. Pero esto va a dejar de ser un problema pronto, pues Mockito 2 permite mockear objetos finales, y aunque aún no tenemos una versión final (actualmente es Release Candidate), ya es perfectamente usable.
En un próximo artículo veremos cómo usarlo.
Una pequeña curiosidad
Kotlin nos permite algo más de flexibilidad que Java al poner nombres a las funciones. Si utilizamos comillas invertidas, podemos poner cualquier texto que se nos ocurra.
Esto puede ser muy útil para los tests, donde lo más importante es que el nombre del test describa perfectamente lo que está haciendo, para que sirva como especificación.
Puedes por tanto tener un test que se llame así:
@Test fun `test something works as expected`() { Assert.assertTrue(false) }
Lo mejor es que, aparte de leerse mucho mejor el código, también se entiende mejor en el output del resultado cuando falla. Verás el error legible de forma más clara.
Si lo utilizas en un proyecto Android, verás que salta un error de Lint indicando que los métodos en proyectos Android no pueden tener espacios. En mis pruebas no he visto que esto sea un problema. Gradle los ejecuta sin problema, así que puedes añadir una anotación para que ignore el error.
En cualquier caso, recuerda usar esto sólo en los tests.
Conclusión
Aunque teóricamente las herramientas de testing que usamos en Java deberían funcionar sin problemas en Kotlin, bien es cierto que aquellas que se basan en reflexión y añaden nulos al código nos pueden dar problemas.
Kotlin es muy cuidadoso con la nulidad, y esto puede ser una pega en algunos casos. Pero cada vez hay más alternativas para hacerlo de forma sencilla, y con Mockito 2 todos esos problemas tienden a desaparecer.
Aparte de estos pequeños escollos, todo lo demás funciona tal y como se haría en Java.
Si te gusta lo que has visto, te animo a que te apuntes al training gratuito, donde te contaré todo lo que necesitas para aprender a crear tus Apps Android en Kotlin desde cero.
0 comentarios