¿Es posible usar Mockito con Kotlin sin abrir la class?

Como probablemente sepamos, por defecto la class Kotlin una vez definida, es definitiva, a less que se declare explícitamente open .

Esto publicaría un desafío cuando queremos simularlo usando Mockito. Necesitamos declararlo explícitamente como open . ¿Hay alguna manera de evitar declararlo como open mientras podemos simularlo para nuestras testings?

Mockito2 ahora puede burlarse de las classs finales también.

Sin embargo, esta function es opcional , por lo que debe habilitarla manualmente.
Para hacerlo, debe definir un file /mockito-extensions/org.mockito.plugins.MockMaker contenga la línea mock-maker-inline

Ver por ej.
http://hadihariri.com/2016/10/04/Mocking-Kotlin-With-Mockito/ o https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#unmockable
para una introducción rápida

en una nota lateral, esto actualmente no funciona para Android

Hay tres forms en que soy consciente de cómo puedes burlarte de las classs de Kotlin:

  1. Usa interfaces en lugar de classs. En este caso, reemplaza todos los usos de una class en particular con la interfaz correspondiente. Y en el código de testing te burlas de la interfaz.

     interface Something { /* ... */ } class SomethingImpl : Something { /* ... */ } fun processSomething(something: Something) { /* ... */ } val something = mock(Something::class.java) processSomething(mock) 
  2. Hacer classs abiertas, lo cual no es muy conveniente.

  3. Use PowerMock en lugar de Mockito. Usando su ClassLoader puedes hacer mucho más que con Mockito.

Prefiero el primer enfoque porque es una buena idea trabajar con interfaces en lugar de classs, incluso si no usa frameworks de burla.

El complemento MockMaker no parece funcionar cuando se ejecutan testings de expreso. Por lo tanto, puedes usar el pugin abierto de Kotlin en su lugar.

Agregue el complemento en build.gradle:

 buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" } } apply plugin: "kotlin-allopen" 

Especifique la anotación que hará que la class se abra:

 allOpen { annotation("com.my.MyMockable") } 

Crea tu anotación que se puede usar para anotar classs:

 @Target(AnnotationTarget.CLASS) annotation class MyMockable 

Luego, para hacer que su class y sus methods públicos sean Mockable (abierto), anótelo con su anotación:

 @MyMockable