Exercising your Kotlin code

To begin exploring how testing can improve the integration and interop experience of our Kotlin code base, we'll start by writing a basic test using Kotlin.

For this example, we'll imagine we're testing how a view model is formatting data so that it can be presented in our UI. We'll test the following function, which takes in String as name and returns that name prepended with Hello:

fun formatGreeting(name: String) : String {
return "Hello $name"
}

We can then write a simple JUnit4 test with Kotlin to test the behavior of our new function:

import org.junit.Assert.*

class UtilitiesKtTest {

@org.junit.Test
fun test_formatGreeting() {
val formattedName = formatGreeting("Nate")
assertEquals("Hello Nate", formattedName)
}
}

At this point, this should look similar to how we write a simple test in Java.

One interesting thing about writing tests in Kotlin is that the naming rules for functions are modified slightly. For test sources, Kotlin allows function names to have spaces in them as long as the full name is wrapped with ` ... `. With this, we can update the name of our test function to something a little less restrictive:

@org.junit.Test
fun `test the formatGreeting function`() {
val formattedName = formatGreeting("Nate")
assertEquals("Hello Nate", formattedName)
}

We also have access to other common testing frameworks, such as Mockito, that you may be familiar with from Java code bases. To demonstrate the use of Mockito, we're going to refactor our formatGreeting() function so that it closely matches a real-world scenario. Let's imagine we don't want to hardcode the greeting string within the implementation of formatGreeting(). Instead, we want to define an interface that will provide a greeting so that we can easily customize and test the behavior of formatGreeting().

To do this, we'll start by defining a new interface, GreetingProvider:

interface GreetingProvider {
fun getGreeting(): String
}

Now, we'll update our formatGreeting() function to take in this GreetingProvider interface and use it to customize the output String:

fun formatGreeting(greetingProvider: GreetingProvider, name: String) : String {
return "${greetingProvider.getGreeting()} $name"
}

Now, we can test this more realistic function by using Mockito to mock out a GreetingProvider interface and control the return value of the getGreeting() function:

@org.junit.Test
fun `test foo`() {
val mockProvider = Mockito.mock(GreetingProvider::class.java)
Mockito.`when`(mockProvider.getGreeting()).thenReturn("Hello")

val formattedName = formatGreeting(mockProvider, "Nate")

assertEquals("Hello Nate", formattedName)
}

These examples have illustrated that testing in Kotlin is not much different than in Java. We can use familiar tools, such as JUnit and Mockito, and apply the same common testing patterns you may be familiar with.