The reason you cannot mock/spy Kotlin classes is they are final (by default). So Mockito cannot mock such classes unless you put the keyword open
.
The Mockito version 2 introduced a feature which allows you to mock/spy final classes.
How to do it?
Add mockito-inline
dependency with other mockito v2 dependencies. For ex: testImplementation 'org.mockito:mockito-inline:2.8.9'
Then use mockito methods as normal.
Here's a dummy test which demonstrates how to mock a method and do nothing.
class Foo {
var xval = 0
fun foo(x: Int, y: Int): Int = x / y
fun bar(x: Int) {
xval = x
}
}
class FooTest {
@Test
fun fooTest() {
val foo = Mockito.mock(Foo::class.java)
Mockito.doAnswer(Answers.RETURNS_DEFAULTS).`when`(foo).foo(10, 2)
assertEquals(0, foo.foo(10, 2))
Mockito.doNothing().`when`(foo).bar(100)
assertEquals(0, foo.xval)
}
}
As you can see, you could return defaults for methods which return something or do nothing for void methods.
Otherwise, you could use mockk
https://mockk.io/ library which doesn't have this issue.
Having said all the above, I suggest that think if you could use an interface/abstract class rather than a concrete class here. That’s the best way to abstract away your dependency using mocking.