0

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!

Kurt Acosta
  • 2,407
  • 2
  • 14
  • 29
  • One of the main goals of your function is to call dependency object. So I don't see any problem with verifying dependecies function call. – Ircover Jun 10 '19 at 10:35
  • Yeah, I agree but I agree more on testing behavior. Mocking inputs and testing what their outputs are. If I test the verification, I'd have to refactor the test every time it changes. In this case, I kind of decided not to test it since it doesn't really have an output. I guess I'll have this as an E2E test rather than a unit test. Though, if I'm wrong please feel free to correct me! – Kurt Acosta Jun 10 '19 at 10:50

0 Answers0