Tests unitarios en Android con Kotlin (KDA 22)
Antonio Leiva

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.

Quizá también te interese…

¿Qué es Kotlin Multiplataforma?

¿Qué es Kotlin Multiplataforma?

En el mundo actual, donde los dispositivos móviles están presentes en nuestra vida diaria, es fundamental para los desarrolladores crear aplicaciones que se adapten a diferentes sistemas operativos. Kotlin Multiplataforma es una herramienta que facilita la creación de...

5 trucos de Kotlin para escribir código más eficiente en Android

5 trucos de Kotlin para escribir código más eficiente en Android

El lenguaje de programación Kotlin se ha convertido en el más popular para el desarrollo de aplicaciones de Android en los últimos años. Su sintaxis concisa y moderna, junto con su capacidad para mejorar la eficiencia de código, lo convierten en una opción atractiva...

Cómo crear un backend en Kotlin usando Ktor

Cómo crear un backend en Kotlin usando Ktor

Ktor es un framework de servidor web ligero y rápido para Kotlin, desarrollado por JetBrains. Es ideal para crear aplicaciones web y servicios RESTful, y es muy fácil de usar y configurar. En este artículo, vamos a ver cómo crear un backend para una aplicación de...

0 comentarios

Enviar un comentario

Los datos personales que proporciones a través de este formulario quedarán registrados en un fichero de DevExpert, S.L.U., con el fin de gestionar los comentarios que realizas en este blog. La legitimación se realiza a través del consentimiento de la parte interesada. Si no se acepta, no podrás comentar en este blog. Los datos que proporciona solo se utilizan para evitar el correo no deseado y no se usarán para nada más. Puede ejercer los derechos de acceso, rectificación, cancelación y oposición en contacto@devexperto.com.

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Acepto la política de privacidad *