Android:使用Kotlin协同程序的ViewModel测试不起作用

时间:2019-02-19 08:18:17

标签: android kotlin kotlinx.coroutines android-viewmodel

我第一次使用协程,但是在ViewModel上测试我的工作时遇到了麻烦。 测试失败并显示

Wanted but not invoked:
observer.onChanged(<Capturing argument>);

测试如下:

val androidVersioningMock: Versioning.AndroidVersioning = mock {
    on { required } doAnswer { "3.3.6" }
}
val versioningMock: Versioning = mock {
    on { android } doAnswer { androidVersioningMock }
}
whenever(networkManager.getAppVersionAsync()).thenReturn(GlobalScope.async { versioningMock })
runBlocking {
    updateVersionModel =
        UpdateViewModel(application, coroutineDispatcherProvider).apply {
            updateLiveData.observeForever(stateObserver)
        }
    verify(stateObserver).onChanged(stateCaptor.capture())
    assertTrue(stateCaptor.lastValue is UpdateState.NoUpdate)
    assertEquals(UpdateState.NoUpdate, stateCaptor.lastValue)
}

我用

嘲笑了coroutineDispatcherProvider
@ExperimentalCoroutinesApi
override val coroutineDispatcherProvider = mock<CoroutineDispatcherProvider> {
    on { main } doAnswer { TestCoroutineContext() }
    on { io } doAnswer { TestCoroutineContext() }
}

在我的ViewModel中,失败的方法是

private suspend fun getUpdateVersion(): Versioning =
    withContext(coroutineDispatcherProvider.io) {
        networkManager.getAppVersionAsync().await()
    }

其执行方式如下:

launch {
    val versioningModel = getUpdateVersion()
    ...
}

我是不是在嘲笑或不做某事?预先感谢!

2 个答案:

答案 0 :(得分:0)

TestCoroutineContext调度程序对于处理测试中的计时很有用,但是您希望同步运行异步调用。您应该可以使用Unconfined调度程序来实现这一点。

答案 1 :(得分:0)

我相信更好的方法是将调度程序传递给viewModels ,因此测试非常容易。 看到这个https://stackoverflow.com/a/62629410/2719243