When I was doing my first unit tests in Kotlin, I started off by adding the needed dependencies:

Mockito, the popular Java mocking library, so that I could mock my interactions and define the behaviors needed for my tests.

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

Kotlin Junit Assertions, which is the standard Junit Kotlin library, providing us with the needed assertion methods.

testCompile org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion}

I followed the old principle of isolating the class under test and mock the interaction with any of the dependencies. However, I quickly found out that there were some issues to overcome when integrating it with Kotlin.

For instance, if I have this class:

And the following test:

We will be facing the first error, which is:

org.mockito.exceptions.base.MockitoException:

Cannot mock/spy class testing.fabiocarballo.com.myapplication.User

Mockito cannot mock/spy because :

- final class

Mockito 1 is only able to mock interactions of non-final classes and methods, whereas Kotlin has final methods and classes as default.

To avoid this you have some options:

Make your class-under-test dependencies to be interfaces. In Java the interface’s methods are not final because they have to be overriden when the interface is implemented by a concrete class. That way, Mockito will be able to mock the interactions with that interface.

Make your Kotlin classes and methods non-final by “opening” them. As I said above, by design Kotlin makes its classes final by default. However, it doesn’t limit the classes to that behavior and you can make them non-final by adding the open keyword to the class and methods that you want to mock. However, I must say that changing the source code for the sake of testing is not the best practice at all.

In this scenario our User class would look like this:

Use Kotlin Test Runner. This runner by Danny Preussler will do the magic work of removing the final modifiers of classes and methods during the test in runtime. Read more about it by the creator here.

You can accomplish this just by adding the proper test runner in your test class.

Tweak Mockito 2.X and mock everything. If you use the newest version of Mockito (2 and above) you are able to mock final classes and methods just by creating the file named org.mockito.plugins.MockMaker under the resources/mockito-extensions directory in your test folder, with only a single line of content that is: mock-maker-inline