Una de las pegas que más se le suele poner a Kotlin, como ya hablábamos en un artículo anterior, es que todas las clases y funciones son por defecto cerradas.

Esto quiere decir que si quieres mockear cualquier clase (algo que puede ser bastante habitual en el testing en Java), necesitas o bien hacerla abierta, con la palabra reservada open, o bien crearte una interfaz por encima.

Ambas opciones pueden ser tediosas, y la verdad es que suponen una limitación cuando la gente viene de programar en Java.

Por suerte, Mockito 2 ha eliminado esta restricción, y hoy te voy a enseñar cómo hacerlo.

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í.

¿Cuál es la problemática?

Imagina que tienes una clase en Kotlin con esta forma:

class ClosedClass {

    fun doSomething() {
    }
}

Y que quieres testear que se llama a su método doSomething.

La forma que tendría el test sería la siguiente:

@Test fun testClosedClass() {
    val c = Mockito.mock(ClosedClass::class.java)
    c.doSomething()
    verify(c).doSomething()
}

Si ejecutas esto con una versión de Mockito 1.x, obtendrás el siguiente error:

Mockito cannot mock/spy following:
– final classes
– anonymous classes
– primitive types

Actualiza las dependencias a Mockito 2

Como hemos dicho, Mockito 2 es capaz de mockearlo todo, así que vamos a actualizar la dependencia. En el momento de escribir este artículo la última versión es la 2.2.6. Pero verifícalo porque están actualizando muy a menudo últimamente.

testCompile 'org.mockito:mockito-core:2.2.6'

Así que ahora volvemos a ejecutar nuestro código, pero… ¡otra vez falla!

Mockito cannot mock/spy because :
– final class

Ya no nos limita mockear clases anónimas o tipos primitivos, pero sí clases finales ¿A qué se debe esto?

Esta opción aún es un poco experimental, y requiere que la activemos a mano.

Activa la opción de mockear clases finales

Para ello, tendrás que crear un archivo en la carpeta test/resources/mockito-extensions llamado org.mockito.plugins.MockMaker :

mockito-2-activacion-clases-finales

Es un simple archivo de texto, en el que hay que escribir:

mock-maker-inline

Nada más.

Ahora ya puedes ejecutar de nuevo el test, y verás que se ejecuta sin problemas. ¡Genial!

Mockear propiedades

También puedes mockear propiedades sin problema. Si cambiamos el código de la clase a este, por ejemplo:

class ClosedClass(val prop: Int) {

    fun doSomething() {
    }
}

Ahora vamos a mockear el valor de la property:

@Test fun testClosedClass() {
    val c = Mockito.mock(ClosedClass::class.java)
    `when`(c.prop).thenReturn(3)

    val prop = c.prop
    assertEquals(3, prop)
}

Cómo ves, le estoy pidiendo que devuelva 3 cuando se le llame, y posteriormente, compruebo que el valor es el correcto.

También puedes comprobar que una propiedad se ha llamado con:

verify(c).prop

Conclusión

Como ves, todas las limitaciones han desaparecido gracias a la nueva actualización de la librería de mocks más conocida para Java.

Ya no hay excusa para que no escribas todos tus tests en Kotlin.

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.

Author: Antonio Leiva

Soy un apasionado de Kotlin. Hace ya más de dos años que estudio el lenguaje y su aplicación a Android para ayudarte a ti a aprenderlo de la forma más sencilla posible.