Helping #AndroidDev to Mock Tests in Kotlin

Roger Silva @orogersilva
AndroidPub
Published in
4 min readFeb 17, 2017

This post was featured in Android Weekly’s #245 issue, Kotlin Weekly #29 and #AndroidDev Digest #132

Kotlin is a programming language of the JetBrains that is characterized by being concise, safe, versatile and interoperable. It is a big trend for Android development context in 2017.

For more details, see https://kotlinlang.org/

And unit tests are required! In an analogy, they are like rebars in a building. Removal of just one of them may bring down the building at any time (similarly, crash the app).

But there is one small problem in mocking unit tests in Kotlin: classes in this language are final, by default. It is necessary to add the openmodifier to extend them. But only to enable mocking on unit testing? No way!

The purpose of this publication is to show how to enable mocking in Kotlin objects without the need to change its (im)mutability property exclusively for unit tests. In addition, I will share some insights I’ve had while implementing some unit tests.

Making it possible

Adding the Mockito-kotlin library

First, be with Kotlin properly setted up on Android Studio. If it is not already, follow the tutorial: https://kotlinlang.org/docs/tutorials/kotlin-android.html

For a developed app without Kotlin, we could simply make use of Mockito framework (http://site.mockito.org) to mock classes for unit tests. However, I will suggest something different. It is the Mockito-kotlin wrapper library. This library make use of Mockito with the support of helper functions for a more idiomatic approach with Kotlin. But, I will write about this library later.

In first place, add Gradle dependency in module-level build.gradle file, like this:

Where x.x.x must be the latest release of the library.

Mockito-kotlin library: https://github.com/nhaarman/mockito-kotlin

Manually or with Gradle tasks?

According to Mockito team:

The lack of mocking finals was a chief limitation of Mockito since its inception in 2007. The root cause was the lack of sufficient support in mock creation / bytecode generation. Until Rafael Winterhalter decided to fix the problem and provide opt-in implementation in Mockito 2.1.0.

Thus, the opt-in solution is to put the following file on the test source set:

Setti

The org.mockito.plugins.MockMaker file contains only the text: mock-maker-inline.

In contrast, this file may be instantiated before running the test methods and deleted after running them through Gradle tasks, like this:

With this configuration through Gradle tasks, to run the unit tests with the help of the graphical interface of the Android Studio, select the menu option Run > Edit Configurations… and so:

What enables testing with the support of the IDE:

Otherwise, just run the tests through the command line: ./gradlew test (Linux/Mac) or gradlew.bat test (Windows).

However, this manual or Gradle tasks setting is temporary, because, according to Mockito team:

In subsequent milestones, the team will bring a programmatic way of using this feature.

The importance of any() method for Kotlin

Let’s see a method header and a check of that method being invoked within a test method:

pubLocalDataSource is a mock object. So, the question is: when pubLocalDataSource mock is called, what happen by passing any<PubDataSource.LoadPubsCallback>() for callback parameter from getPubs method? It depends! If the framework used is Mockito, it will be thrown a NullPointerException, because callback is non-nullable and any method returns a null value. An alternative would be make callback parameter nullable. But, it is not recommended, because it would meet a need exclusively for a test method. That is no good (in fact, it is a bad practice)! The Mockito-kotlin tries to solve this issue creating actual instances to return when any method is invoked, thus maintaining the correctness of the test method.

Conclusion

As mentioned earlier, the goal of this publication is to make possible to mock Kotlin objects through different types of configuration. Also, it was presented the Mockito-kotlin library, that offers some ease for mocking that Kotlin objects.

Here is an example of open source project that contains some implemented unit tests: https://github.com/orogersilva/super-pub-android. In the future, I intend to add some Android instrumentation tests too.

Thanks for reading this publication. Be sure to click ❤ to recommend this publication, if you found it helpful.

Follow me at Twitter and Github. There I will be continuously sharing other content about Android development.

See you later! :)

--

--

Roger Silva @orogersilva
AndroidPub

I’m Mobile Specialist #AndroidDev / Technical Writer / Conference Speaker / Blogger / Football Fan