1
@Test
fun sendResultToUI() {

    val foo = MutableLiveData<Resource<User>>()
    val bar = MutableLiveData<Resource<User>>()
    `when`(userRepository.loadUser("foo")).thenReturn(foo)
    `when`(userRepository.loadUser("bar")).thenReturn(bar)
    val observer = mock<Observer<Resource<User>>>()
    userViewModel.user.observeForever(observer) //Create foo and bar, observe user live data

    userViewModel.setLogin("foo")
    verify(observer, never()).onChanged(any()) //Make sure that setting login to foo did not touch vm.user?

    /*val fooUser = TestUtil.createUser("foo")
    val fooValue = Resource.success(fooUser)
    foo.value = fooValue
    verify(observer).onChanged(fooValue)
    reset(observer)

    val barUser = TestUtil.createUser("bar")
    val barValue = Resource.success(barUser)
    bar.value = barValue
    userViewModel.setLogin("bar")
    verify(observer).onChanged(barValue)*/
}

Can anyone please explain wtf this line: verify(observer, never()).onChanged(any()) is doing in Google's GithubBrowser sample? I just don't understand it, calling setLogin() fires the observer so how the hell can we verify that onChanged() was never called when we specifically triggered it on the previous line!?

Daniel Wilson
  • 18,838
  • 12
  • 85
  • 135

1 Answers1

1

calling setLogin() fires the observer

No, calling setLogin just return your a foo LiveData, the underlying value is not updated yet until you set it (foo.value = fooValue). So this line tests onChange is not called if no value received.

jaychang0917
  • 1,880
  • 1
  • 16
  • 21
  • Thanks @jaychang0917, so calling `setLogin` normally triggers the `user` live data to call `userRepository.loadUser(login)`, but we override that with ``when`(userRepository.loadUser("foo")).thenReturn(foo)`. But the user live data switchmap is still triggered, does this not mean the `observer` in the test was changed? – Daniel Wilson Sep 06 '18 at 09:12
  • ya, the `switchmap` is triggered, but the `userRepository` is a mocked object, so `loadUser` will not set the value of underlying `LiveData`, so `onChange` is not going to be called. – jaychang0917 Sep 06 '18 at 09:23
  • Okay thank you I think it makes sense! So basically it is confirming that `setLogin` did nothing except for loading a mocked foo. And in the next step it makes sure that setting a value on that mocked foo *is* observed. I think `sendResultToUI` is a very confusing name for this test :) – Daniel Wilson Sep 06 '18 at 17:53