Android 类的协同程序单元测试失败
在单元测试协同过程中,我面临一个奇怪的问题。这个类上有两个测试,当分别运行时,它们都通过了,当我运行完整的测试类时,一个失败,并出现断言错误。 我正在使用Android 类的协同程序单元测试失败,android,unit-testing,kotlin-coroutines,Android,Unit Testing,Kotlin Coroutines,在单元测试协同过程中,我面临一个奇怪的问题。这个类上有两个测试,当分别运行时,它们都通过了,当我运行完整的测试类时,一个失败,并出现断言错误。 我正在使用MainCoroutineRule来使用TestCoroutineScope并依赖于最新的Coroutine测试库 以下是测试: @Test fun testHomeIsLoadedWithShowsAndFavorites() { runBlocking { // Stubbing ne
MainCoroutineRule
来使用TestCoroutineScope
并依赖于最新的Coroutine测试库
以下是测试:
@Test
fun testHomeIsLoadedWithShowsAndFavorites() {
runBlocking {
// Stubbing network and repository calls
whenever(tvMazeApi.getCurrentSchedule("US", currentDate))
.thenReturn(getFakeEpisodeList())
whenever(favoriteShowsRepository.allFavoriteShowIds())
.thenReturn(arrayListOf(1, 2))
}
mainCoroutineRule.runBlockingTest {
// call home viewmodel
homeViewModel.onScreenCreated()
// Check if loader is shown
assertThat(LiveDataTestUtil.getValue(homeViewModel.getHomeViewState())).isEqualTo(Loading)
// Observe on home view state live data
val homeViewState = LiveDataTestUtil.getValue(homeViewModel.getHomeViewState())
// Check for success data
assertThat(homeViewState is Success).isTrue()
val homeViewData = (homeViewState as Success).homeViewData
assertThat(homeViewData.episodes).isNotEmpty()
// compare the response with fake list
assertThat(homeViewData.episodes).hasSize(getFakeEpisodeList().size)
// compare the data and also order
assertThat(homeViewData.episodes).containsExactlyElementsIn(getFakeEpisodeViewDataList(true)).inOrder()
}
}
另一个测试几乎类似于测试没有收藏夹的节目。我正在尝试测试HomeViewModel
方法,如下所示:
homeViewStateLiveData.value = Loading
val coroutineExceptionHandler = CoroutineExceptionHandler { _, exception ->
onError(exception)
}
viewModelScope.launch(coroutineExceptionHandler) {
// Get shows from network and favorites from room db on background thread
val favoriteShowsWithFavorites = withContext(Dispatchers.IO) {
val favoriteShowIds = favoriteShowsRepository.allFavoriteShowIds()
val episodes = tvMazeApi.getCurrentSchedule(COUNTRY_US, currentDate)
getShowsWithFavorites(episodes, favoriteShowIds)
}
// Return the combined result on main thread
withContext(Dispatchers.Main) {
onSuccess(favoriteShowsWithFavorites)
}
}
}
我找不到为什么单独运行的测试通过,而当测试整个类时,其中一个测试失败的实际原因。如果我遗漏了一些东西,请提供帮助。Coroutine支持提供的改装和空间所有者暂停功能,并自行将其从UI线程中移出。因此,它们大大减少了开发人员处理线程回调的麻烦。最初,我通过
Dispatchers.IO
明确地将网络和数据库的挂起调用移动到IO。这是不必要的,也会导致不必要的上下文切换,从而导致测试失败。由于库会自动执行此操作,所以只需在UI上处理可用的数据即可
viewModelScope.launch(coroutineExceptionHandler) {
// Get favorite shows from db, suspend function in room will launch a new coroutine with IO dispatcher
val favoriteShowIds = favoriteShowsRepository.allFavoriteShowIds()
// Get shows from network, suspend function in retrofit will launch a new coroutine with IO dispatcher
val episodes = tvMazeApi.getCurrentSchedule(COUNTRY_US, currentDate)
// Return the result on main thread via Dispatchers.Main
homeViewStateLiveData.value = Success(HomeViewData(getShowsWithFavorites(episodes, favoriteShowIds)))
}
协同程序支持附带的改进和空间拥有者暂停功能,并自行将它们从UI线程中移出。因此,它们大大减少了开发人员处理线程回调的麻烦。最初,我通过
Dispatchers.IO
明确地将网络和数据库的挂起调用移动到IO。这是不必要的,也会导致不必要的上下文切换,从而导致测试失败。由于库会自动执行此操作,所以只需在UI上处理可用的数据即可
viewModelScope.launch(coroutineExceptionHandler) {
// Get favorite shows from db, suspend function in room will launch a new coroutine with IO dispatcher
val favoriteShowIds = favoriteShowsRepository.allFavoriteShowIds()
// Get shows from network, suspend function in retrofit will launch a new coroutine with IO dispatcher
val episodes = tvMazeApi.getCurrentSchedule(COUNTRY_US, currentDate)
// Return the result on main thread via Dispatchers.Main
homeViewStateLiveData.value = Success(HomeViewData(getShowsWithFavorites(episodes, favoriteShowIds)))
}
你能链接说明上下文切换是在这些库内部完成的文档吗?你能链接一下说明上下文切换是在这些库内部完成的文档吗?非常感谢。