当运行使用withContext(Dispatchers.Main)
的kotlin suspend方法的单元测试时,测试方法失败,但有以下例外:
我的协同程序库版本是kotlinx-coroutines-core:1.1.1和kotlinx-coroutines-android:1.1.1
示例:
suspend fun methodToTest() {
withContext(Dispatchers.Main) {
doSomethingOnMainThread()
val data = withContext(Dispatchers.IO) {
doSomethingOnIOThread()
}
}
}
此外,当我删除withContext(Dispatchers.Main)
时,它工作正常。
java.lang.IllegalStateException: Module with the Main dispatcher had failed to initialize. For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used
at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.missing(MainDispatchers.kt:79)
at kotlinx.coroutines.internal.MissingMainCoroutineDispatcher.isDispatchNeeded(MainDispatchers.kt:54)
at kotlinx.coroutines.DispatchedKt.resumeCancellable(Dispatched.kt:373)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:25)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:152)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source)
7条答案
按热度按时间wqsoz72f1#
当运行测试时,例如为ViewModel运行协程时,您最有可能遇到以下异常
java.lang.IllegalStateException:具有Main调度程序的模块未能初始化。对于测试,可以使用kotlinx-coroutines-test模块中的Dispatchers.setMain
这背后的原因是在测试环境中缺少
Looper.getMainLooper()
,而实际应用程序中存在Looper.getMainLooper()
。要解决这个问题,您需要用TestCoroutineDispatcher
替换主调度程序确保您的Gradle文件具有协同程序测试依赖关系
"org. jetbrains. kotlinx:kotlinx协同程序-测试:$协同程序版本"
在测试类上定义以下内容-〉使用
@ExperimentalCoroutinesApi
注解类注意:如果您有
CoroutineDispatcher
,您也可以将Dispatchers.Main
作为仓库的构造函数依赖项进行传递。建议不要在仓库/视图模型等WATCH-THIS上硬编码您的调度程序PLEASEEEEEEEE为什么不可扩展:您需要在每个测试类上复制并粘贴相同的代码
在此解决方案中,您将创建自定义规则。在测试包上添加实用程序类
如果您需要有关上述实用程序类的说明,请参阅以下代码实验
在你的测试类中,只需要添加以下代码行,你就可以开始了:
我想如果你有很多测试类,你就会明白为什么它是可伸缩的。
您也可以使用
Dispatchers.Unconfined
LINK一种不局限于任何特定线程的协同程序调度程序。它在当前调用帧中执行协同程序的初始延续,并使协同程序在相应的挂起功能所使用的线程中恢复,而不要求任何特定的线程策略。在这种调度程序中启动的嵌套协同程序形成一个事件循环,以避免堆栈溢出。
您可以按如下方式添加它
快乐编码......
nvbavucw2#
您没有访问Dispatchers. Main的权限,请在单元测试中
参见https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/
Dispatchers.Main Delegation
部分详细解释了您需要做什么。pn9klfpd3#
在我的例子中,我已经为单元测试设置了主协程调度器,但仍然不时地看到一些错误。
我已经添加到构建.gradle在这里:
我再也看不到那个错误了。
yshpjwxd4#
现在你可以把这个添加到你的测试中:
或其他调度程序..这是实验但它工作!
t0ybt7op5#
这是因为缺少Dispatcher.Main而引发的。它基于Android,因此不能用于单元测试。解决方案在Coroutines团队的文档中。下面是一个解决了我的问题的示例,并包含在文档中。
您应该注意的是
newSingleThreadContext("UI Thread")
和Dispatchers.setMain(mainThreadSurrogate)
,它们在任何测试之前被调用,以便创建主调度程序。baubqpgj6#
我遇到了同样的问题,我在这里找到了解决方案kotlinx.coroutines,解决方案是使用协程1. 1. 0版,我尝试了一下,现在它工作得很完美
q35jwt9p7#
TestCoroutineDispatcher
是现在deprecated.这建议的方法是到使用UnconfinedTestDispatcher
象下面参见设置主调度程序