Mockito and testing Kotlin classes

Hey there! š»
Did you switch to Kotlin or yet wondering? Just do it!
However, there're always some inconveniences like the one I will describe in this post.
Problem
You started happy coding your amazing apps in Kotlin but when unit testing time has come... Bam! You cannot test final classes with Mockito 1.x and receive the following error:
Mockito cannot mock/spy following:
ā final classes
ā anonymous classes
ā primitive types
By default the Kotlin classes are final.
There're mainly three solutions:
- Switch to Mockito 2.x
- Using interfaces which classes under testing should implement and then test the interfaces instead of the concrete classes
- Use the proposed solution which works with Mockito 1.x
Solution
Starting from Kotlin 1.0.6 you can use the all-open
compiler plugin which makes classes annotated with a specific annotation and their members open without explicitly using the keyword open in front of the class declaration.
First, we have to create the annotation class:
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class TestOpen
Second, we need to apply the all-open
plugin in the app's build.gradle file:
buildscript {
ext.kotlin_version = '1.0.6'
repositories {
jcenter()
}
dependencies {
...
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
}
}
And configure it in the module's build.gradle file:
apply plugin: 'kotlin-allopen'
allOpen {
annotation("[PATH_TO_ANNOTATION_CLASS].TestOpen")
}
And then simply annotate the classes with this annotation:
@TestOpen
class TasksRepository {
...
}
Beware!
Classes become open not only during tests!
all-open
plugin actually opens all annotated classes for testing configurations!
Hope that this post will save you some time researching the issue!
Happy coding! šš¼
Comments ()