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.2.0'
implementation 'org.koin:koin-android:2.0.1'
/* … */
testImplementation 'androidx.arch.core:core-testing:2.1.0'
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.