如何将其他调度程序注入 MainCoroutineRule?



在 Google Codelab for Coroutines 中,我们看到了一个MainCoroutineScopeRule。在该规则中,它解释了除了Dispatchers.Main之外,此规则还可以扩展到其他调度程序:

override fun starting(description: Description?) {
super.starting(description)
// If your codebase allows the injection of other dispatchers like
// Dispatchers.Default and Dispatchers.IO, consider injecting all of them here
// and renaming this class to `CoroutineScopeRule`
//
// All injected dispatchers in a test should point to a single instance of
// TestCoroutineDispatcher.
Dispatchers.setMain(dispatcher)
}

我的问题是,我们究竟如何注入其他调度员?这是否假设我们正在使用依赖注入?如果是这样,如果我不使用 DI,我是否仍可以将此规则扩展到其他调度程序?我在 kotlinx-coroutines-test 库中没有看到任何允许我将TestCoroutineDispatcher设置为其他调度程序的内容。所以,有这个:

Dispatchers.setMain(dispatcher)

。但不是这个:

Dispatchers.setIO(dispatcher) // Or Default, etc.

我是否应该重写我的suspend函数以将调度程序作为参数:

suspend doSomeIO(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
launch(dispatcher) {
// Some long-running IO operation
}
}

您是正确的,因为这确实假设您正在注入调度程序。 如果不使用主调度程序,则应注入调度程序以正确测试它。

编写挂起函数的方式是一种方法,如果要强制该特定函数位于 Dispatchers.IO 线程上。 但是,您最终将拥有嵌套启动。

取而代之的是,我只是将调度程序传递给视图模型,并让视图模型决定如何调用挂起函数。

//Your version:

suspend fun doSomeIO(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
launch(dispatcher) {
// Some long-running IO operation
}
}
class MyViewModel(val dispatcher: CoroutineDispatcher = Dispatchers.IO: ViewModel() {
init {
viewModelScope.launch {
doSomeIO(dispatcher) // here you are launching one coroutine inside the other
}
}
}
// Instead try this: 
suspend fun doSomeIO() {
// Some long-running IO operation
}
class MyViewModel(val dispatcher: CoroutineDispatcher = Dispatchers.IO: ViewModel() {
init {
viewModelScope.launch(dispatcher) {
doSomeIO()
}
}
}

最新更新