使用协程测试简单的加载+获取流程,就像使用 StandardTestDispatcher 进行 Android 仪器测试一样

kap*_*inz 5 android ui-testing dispatcher coroutine kotlin

我想在 Android 中测试以下非常常见的用例作为仪器测试:

  • 单击按钮时,我的 ViewModel 中会调用 fetch() 函数
  • 该函数告诉视图显示加载覆盖
  • 它在协程中执行提取
  • 获取结果后,它让视图知道显示结果

这是我的 Viewmodel 中的函数:

fun fetch() {
    _loading.value = true //loading is shown
    viewModelScope.launch {
        val results = fetchUseCase() //suspend function
        _result.postValue(results)
        _loading.postValue(false) //loading is not displayed
    }
}
Run Code Online (Sandbox Code Playgroud)

这是根据此 CodeLab https://developer.android.com/codelabs/advanced-android-kotlin-training-testing-survey#4进行的测试:

@HiltAndroidTest
@UninstallModules(CoroutinesDispatcherModule::class)
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTestJunit4Deprecated {

@get:Rule
var hiltRule = HiltAndroidRule(this)

@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = MainCoroutineRule()

@Before
fun setup() {
    ActivityScenario.launch(HomeScreenActivity::class.java)
}

@ExperimentalCoroutinesApi
@Test
fun fetchTest() {

    //pausing the long running tasks
    mainCoroutineRule.pauseDispatcher()

    //When clicking the button
    onView(withId(R.id.load_measurement_button)).perform(click())

    //loading is shown
    onView(withId(R.id.loading_overlay))
        .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))

    //continue fetch
    mainCoroutineRule.resumeDispatcher()

    // loading is not shown anymore and the result is there
    onView(withId(R.id.loading_overlay))
        .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)))
    onView(withId(R.id.message))
        .check(matches(withText("0")))
}
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,“pauseDispatcher()”和“resumeDispatcher”已被弃用。我尝试使用“StandardTestDispatcher”和“advanceUntilIdle()”,但它无法按预期工作。协程永远不会恢复。如何重写该测试,使其有效:

  • 没有不推荐使用的函数调用
  • 不改变生产代码?