I'm having problems on how to unit test my view model function.
class MyViewModel(
private val dependency: Dependency
) : ViewModel() {
private val _myFunctionState = MutableLiveData<State>()
val myFunctionState: LiveData<State> = _myFunctionState
fun myFunction() {
viewModelScope.launch(CoroutineExceptionHandler { _, throwable ->
_myFunctionState.postValue(State.Error(throwable)
}) {
_myFunctionState.postValue(State.Loading)
dependency.callFunction()
_myFunctionState.postValue(State.Success)
}
}
}
Now, if dependency.callFunction()
were to return something, I could easily test if I got the value and do an assertion like liveData.value shouldBe valueFromFunction
but in this case, the function just executes something
I've considered using verification to test it
fun test_myFunction() {
val dependency = mockk<Dependency>(relaxed = true)
val viewModel = MyViewModel(dependency)
viewModel.myFunction()
coVerify { dependency.callFunction() }
confirmVerified(dependency)
}
But if I go this route, this is already testing implementation details. I should be testing behavior so I decided to test the state
fun test_myFunction() {
val dependency = mockk<Dependency>(relaxed = true)
val viewModel = MyViewModel(dependency)
viewModel.myFunction()
viewModel.myFunctionState.value shouldBe State.Success
}
Since this is a coroutine, the execution would stop on dependency.callFunction()
and only resume and emit the State if it is successful. Now this tests behavior, however, what if a developer removes the dependency call? Now the test would still pass without calling the dependency.
Should I just go ahead and test implementation and verify the dependency call? Or should I just skip this test?
Many thanks!