Improve your tests with Kotlin in Android — (Pt.1 )
Hey there! Since I’ve started playing with Kotlin, I quickly fell in love with the language and soon understood how it would improve my productivity and readability of my code. Following that idea (and thanks to an awesome open-source community) I was able to improve the tests of my Android project using Kotlin.

This will be a series that will overlook on how to start testing your Java/Kotlin code using Kotlin and which are the must-have libraries and framework to do it.
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

Mockito matchers rely on null-values as the return values as in any()
or anyObject()
, whereas Kotlin was designed to avoid null types.
Regarding this problem, you can do your own workarounds, but I really advise everyone to mockito-kotlin which solves this problem and offers a lot more functionality with it.
To make your tests work you just have to replace this code:
@Test
fun englishGreetIsCorrect() {
Mockito.`when`(user.fullName()).thenReturn("Fábio Carballo") assertEquals(
"Hello, Fábio Carballo!",
tested.getEnglishGreeting())
}
By this:
@Test
fun englishGreetIsCorrect() {
whenever(user.fullName()).thenReturn("Fábio Carballo")
assertEquals(
"Hello, Fábio Carballo!",
tested.getEnglishGreeting())
}
As you can see, it follows the same idiomatic flow and becomes easier to read.
However, this is just one of the thing that mockito-kotlin improves .. On the next story, I will further explore this library and how it improved the quality of my tests.
If you want to, check the part 2 as well. Thanks! 😄