Unit Testing ViewModel

This post describes how to Unit Test the ViewModel in MVVM. If you don’t know what MVVM is, please read Basic MVVM in Android first.

Why Write Unit Test?

It will help you to structure the code and you can tested it before writing the View. You can also create fake Models and create the View without any need for a connection to a database or a server.

You can prevent to break the code in the future. After a while, you will forgot how the code works or someone else may change it. The Unit Test will detect logical errors in the new code.

It will help you to documentation the code. The Unit Test is an example how the ViewModel and Model works.

Unit Test in Android Studio

Android Studio have a build in support for writing Unit Test using JUnit. LiveData and injection is setup before the test begin.

Library Dependency

Add dependency for MVVM Unit Test and Koin in the build gradle file.

dependencies {
    /* … */
    implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
    implementation 'org.koin:koin-android:2.0.1'
    /* … */
    testImplementation 'androidx.arch.core:core-testing:2.0.1'
    testImplementation 'org.koin:koin-test:2.0.1'
    /* … */
}

Setup Rule for LiveData

The UnitTest class needs to inhere from the KoinTest class for the Model injection. The rule will execute the LiveData at once.

class MainViewModelUnitTest: KoinTest {
    @Rule
    @JvmField
    val rule = InstantTaskExecutorRule()
}

Inject the Models for running Test

The Unit Test call Before and After between that the test run. The After method inject the fake Models. The after method stops Koin.

    /* … */
    @Before
    fun before() {
        startKoin {
            modules(module {
                single<TodoModel> { FakeTodoModel() }
            })
        }
    }

    @After
    fun after() {
        stopKoin()
    }
    /* … */

Write the Test

During the test, LiveData need to be observe before reading the value.

    // Test if toggle update the todoList.
    @Test
    fun testToggleTodo() {
        val viewModel = MainViewModel()

        todoModel.todoList.observeForever { }

        viewModel.toggleComplete(0)
        assert(todoModel.todoList.value!![0].complete)

        viewModel.toggleComplete(1)
        assert(!todoModel.todoList.value!![1].complete)
    }

Summary

Writing Unit Test for your App and ViewModel can increase the quality of your code, prevent strange behaviors in the future and document the project.

An example shows how create a Unit Test in Android Studio. How to setup up a rule for LiveData and how to inject a fake Model for the test.

You can find the source files on GitHub!