· 4 min read

Unit tests on Android with Kotlin (KAD 22)

Of course, Kotlin also allows us to do unit tests in a very simple way, and very similar to what we’re used in Java.

There are some small complications when we use libraries like Mockito, but we’ll see some tricks to make it easier.

If all this passionate you as to me, I encourage you to sign up for my free training where I will tell you everything you need to learn about how to create your Android Apps in Kotlin from scratch.

Action View

Unit tests in Kotlin

Although the subject of what a unitary test is always generates controversy, I won’t go into details here about this topic.

For our particular example, it’s enough to think that a unit test is a test that doesn’t need a device to run. The IDE will be able to execute them and display a result, identifying which ones were executed and which ones failed.

Configure Gradle

You need to add jUnit to your dependencies. It’s possible that, when you created the project, it was already included by default. We’ll also add Mockito, as we’ll use it later:

testCompile "junit:junit:4.12"
testCompile "org.mockito:mockito-core:1.10.19"

Create your first test

In the app/src/test folder (you can create it if it doesn’t exist yet), you can create a new class called MyTest, which looks like this:

class MyTest {

    @Test
    fun testsWork() {
        assertTrue(true)
    }
}

As you can see, it’s very similar to what you’re used to in Java.

How to use Mockito

Mockito in Kotlin can be used like any other library, although it’s true that you could find some complications that you’ll need to solve.

Here’s an example from the book:

@Test 
fun emptyDatabaseReturnsServerValue() {
    val db = Mockito.mock(ForecastDataSource::class.java)
    val server = Mockito.mock(ForecastDataSource::class.java)
    `when`(server.requestForecastByZipCode(any(Long::class.java), any(Long::class.java)))
            .then { ForecastList(0, "city", "country", listOf()) }

    val provider = ForecastProvider(listOf(db, server))
    assertNotNull(provider.requestByZipCode(0, 0))
}

You see, everything is very similar. You can create your mocks and use them seamlessly throughout the code. Although I’m not doing it here, you could also use ‘MockitoJUnitRunner’ and annotations.

The word when is a reserved word in Kotlin, so you need to use inverted commas, or you could even rename the import and give it the name you want:

import org.mockito.Mockito.`when` as _when

The problem arises when trying to mock types that don’t allow null values. Mockito by default gives null values to mocked objects, so sooner or later problems will arise.

A little trick is to use a library like mockito-kotlin, which instead of using nulls, will give specific values by default to each type, solving that problem. In addition, it provides other functions that take advantage of Kotlin’s power to make things simpler.https://antonioleiva.com/mockito-2-kotlin/

Another problem is that, by default, all classes and functions in Kotlin are closed, which means that they can’t be extended. This is a problem for Mockito, which won’t be able to mock them.

But that’s not an issue anymore, because Mockito 2 allows mocking final objects.

In an upcoming article we’ll see how to use it.

A little interesting thing

Kotlin allows us more flexibility than Java by naming functions. If we use inverted commas, we can put any text that comes to our mind.

This can be very useful for tests, where the most important thing is that the name of the test perfectly describes what you are doing, so as to be able to serve as specification.

Therefore, you can have a test that is named like this:

@Test fun `test something works as expected`() {
    Assert.assertTrue(false)
}

The best thing is that, apart from improving readability, it is also better understood in the output of the result when it fails. You’ll see the readable error more clearly.

If you use it on an Android project, you’ll see that it shows a Lint error indicating that methods on Android projects can’t have spaces. In my tests I haven’t noticed that this can be a problem. Gradle runs them without problem, so you can add an annotation to ignore the error.

In any case, remember to use this only for tests.

Conclusion

Although theoretically the testing tools that we use in Java should work without problems in Kotlin, it’s true that those that are based on reflection and add null to the code can give us problems.

Kotlin is very careful about nullity, and this can be a sticking point in some cases. But increasingly, there are more alternatives to do it in a simple way, and with Mockito 2 all those problems tend to disappear.

Apart from these small pitfalls, everything else works just as it would in Java.

And if you want to learn how to use Kotlin to develop your own Android Apps, I recommend you take a look at my free training. Reserve your place!

    Share:
    Back to Blog