如何使用junit和mockito测试从switchMap派生的Android Live Data?

syl*_*bix 7 android unit-testing mockito kotlin android-livedata

我正在编写一个单元测试,以断言LiveData使用期望的参数调用观察者。LiveData通过使用InstantTaskExecutorRule,模拟观察者并通过observeForever方法观察数据,我进行了成功的测试。

当使用与LiveDataTransformations.switchMap断言派生的方法相同时,将失败。

例如:

class LoginViewModel {
    @Inject lateinit var service: LoginService

    val passwordField = ObservableField<String>()

    private val loginInput = SingleLiveEvent<String>()
    val loginEvent: LiveData<UserNotification> = 
    Transformations.switchMap(loginInput, { password ->
        service.login(password)
    })

    fun login() {
       loginInput.value = passwordField.get()
    }
}
Run Code Online (Sandbox Code Playgroud)

*摘自Google Samples Repo的 SingleLiveEvent

然后进行相应的测试(使用mockito_kotlin):

class LoginViewModelTest {

@Rule
@JvmField
val rule = InstantTaskExecutorRule()

//...Setup mock login service, assign it to the view model to be tested, etc

@Test
fun login() {
    val observer = mock<Observer<UserNotification>>()
    loginViewModel.loginEvent.observeForever(observer)
    loginViewModel.passwordField.set(testPassword)
    loginViewModel.login()

    //Theese verify checks report zero interactions
    verify(loginService, atLeastOnce()).login(testPassword)
    verify(observer).onChanged(expectedNotification)
}
Run Code Online (Sandbox Code Playgroud)

Mockito报告说,两个模拟(登录服务和观察者)的交互均为零,并且测试失败。

关于如何实现此测试,以便正确调用模拟类的任何想法?

提前致谢!

附加条款:

  1. 我尝试CountingTaskExecutorRule结合使用和,Awaitility以等待verifyCountingTaskExecutorRule报告空闲时执行对的调用,但是没有运气。

  2. login对服务回报方法LiveData