Using Mockito with Kotlin 1.0
This post refers to Kotlin 1.0. Hopefully Kotlin syntax will stay fairly stable now.
For this post I used Mockito, JUnit and fest-assert.
TL;DR
Here’s the TL;DR for people who just want to get mocking.
- Include Mockito like usual. You don’t need any special Kotlin wrapper.
-
You generally need backticks around Mockito static methods:
val client = Mockito.`mock`(MyServiceClient::class.java)
-
And the above snippet also shows how to refer to an object’s class.
-
You must either mark your functions
open
if you’d like to stub them or else create an interface and mock that. Mockito won’t throw any exceptions if you mock a class with non-open
functions but your stubbing won’t work correctly. - If you absolutely must mock a concrete classes rather than interfaces, they have to be marked
open
(i.e. non-final).
More Learning
This is my Kotlin class. The callService
method throws an exception so that we can tell if we are getting that implementation or a mocked implementation. The class is marked open
because Kotlin classes are final by default.
Here is the Java version of my test.
Here is the Kotlin version of my test.
Both tests fail! Bummer. While client
is mocked (it has a class like MyServiceClient$$EnhancerByMockitoWithCGLIB$$e0ad046f
) calling methods on the mock still ends up executing the implementation on the concrete class. That’s because the function in question is not marked open
.
It turns out you need to mock interfaces rather than concrete classes or else mark your methods open
.
If you decide to mark your methods open
then that’s all you need to do.
If you choose to mock interfaces, here’s how it’ll look. Note that the class no longer needs to be marked open
(since we aren’t mocking it) and the concrete class’ callService
method must be marked with override
.
Here I’ve modified our original test so that it passes and added a new test that mocks the interface.
Success!