Unit Testing in android — Part 2

rahul reddy
2 min readOct 7, 2018

--

This blog is the part 2 of the this blog. Previous blog was about unit testing in java. This blog will be about doing the same in Kotlin. Consider the below presenter, view and activity:

SplashScreenPresenter.kt:

package com.example.rahulreddy.kotlinexample.splash

class SplashScreenPresenter(private val splashView: SplashScreenView) {

fun navigateToNextScreen(userName: String?) {
if (userName != "") {
splashView.goToHomeScreen(userName)
} else {
splashView.goToLoginScreen()
}
}
}

SplashScreenActivity.kt:

package com.example.rahulreddy.kotlinexample.splash

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.example.rahulreddy.kotlinexample.R
import com.example.rahulreddy.kotlinexample.login.LoginScreenActivity
import com.example.rahulreddy.kotlinexample.home.HomeScreenActivity


@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class SplashScreenActivity : AppCompatActivity(), SplashScreenView {

override fun goToLoginScreen() {
val intent = Intent(this, LoginScreenActivity::class.java)
startActivity(intent)
finish()
}

override fun goToHomeScreen(userName: String?) {
val intent = Intent(this, HomeScreenActivity::class.java)
intent.putExtra("name", userName)
startActivity(intent)
finish()
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash_screen)
val preference = getSharedPreferences("session", Context.MODE_PRIVATE)
val name = preference.getString("name", "")
SplashScreenPresenter(this).navigateToNextScreen(name)
}
}

SplashScreenView.kt:

package com.example.rahulreddy.kotlinexample.splash

interface SplashScreenView {
fun goToLoginScreen()
fun goToHomeScreen(userName: String?)
}

To write the unit tests for this presenter we need to mock the view. For this we can use mockito. To add mockito to your project add the below line to your build.gradle

testImplementation "org.mockito:mockito-core:1.10.19"

also make sure that the below line is present in the build.gradle

testImplementation 'junit:junit:4.12'

Now go to your presenter and do a ‘cmd + shift + T’ or the equivalent in your key map and let android studio to automatically create a test for you and create tests in this file.

The most general type of testing in presenter is to verify if the correct function in the view is called from the presenter. For this we can use the ‘Mockito.verify’. It will verify if the corresponding function of the mocked object is called. For the above example this looks like below:

package com.example.rahulreddy.kotlinexample.splash

import org.junit.Test
import org.mockito.Mockito

class SplashScreenPresenterTest {

@Test
fun testNavigateToNextScreenBasedOnUserNameWhenUserNameIsNotEmpty() {
val mockedSplashScreenViewObject = Mockito.mock(SplashScreenView::class.java)
val splashScreenPresenter = SplashScreenPresenter(mockedSplashScreenViewObject)
val userName = "rahul"
splashScreenPresenter.navigateToNextScreen(userName)
Mockito.verify(mockedSplashScreenViewObject).goToHomeScreen(userName)
}
}

If you notice the Junit doesn’t allow you name the test freely. You need to follow the name conventions of function in Kotlin/Java. But in Kotlin we can name a function whatever we want by using inverted commas. This will be most helpful in case of tests as now we can name a test to completely describe what it does. In code this looks like below.

package com.example.rahulreddy.kotlinexample.splash

import org.junit.Test
import org.mockito.Mockito

class SplashScreenPresenterTest {

@Test
fun testNavigateToNextScreenBasedOnUserNameWhenUserNameIsNotEmpty() {
val mockedSplashScreenViewObject = Mockito.mock(SplashScreenView::class.java)
val splashScreenPresenter = SplashScreenPresenter(mockedSplashScreenViewObject)
val userName = "rahul"
splashScreenPresenter.navigateToNextScreen(userName)
Mockito.verify(mockedSplashScreenViewObject).goToHomeScreen(userName)
}

@Test
fun `when user name is empty in splash screen navigate to login screen`() {
val mockedSplashScreenViewObject = Mockito.mock(SplashScreenView::class.java)
val splashScreenPresenter = SplashScreenPresenter(mockedSplashScreenViewObject)
splashScreenPresenter.navigateToNextScreen("")
Mockito.verify(mockedSplashScreenViewObject).goToLoginScreen()
}
}

As we can see that the unit tests can only cover non android logic. So in order to fully test the app one should also have integration tests in place. Only having unit test will not help much in finding the exact location bug in code.

--

--