获得Kotlin错误“等待60000毫秒后,Test Coroutine未完成”。
我是新手的测试,试图进行第二流量并断言它,当我一一运行该测试时,运行良好,但是当我运行整个测试时,一旦第一次测试运行正常,其余的测试就会给我超时错误。
错误 :
After waiting for 60000 ms, the test coroutine is not completing
kotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 60000 ms, the test coroutine is not completing
at app//kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$3$3.invokeSuspend(TestBuilders.kt:304)
(Coroutine boundary)
@OptIn(ExperimentalCoroutinesApi::class)
class HomeViewModelTest {
private lateinit var viewModel: HomeViewModel
private val testDispatcher = UnconfinedTestDispatcher()
@Before
fun setup() {
viewModel = HomeViewModel(FakeOrderRepository())
Dispatchers.setMain(testDispatcher)
}
@After
fun tearDown() {
Dispatchers.resetMain()
testDispatcher.cancel()
}
@Test
fun flowViewModelTesting1() = runTest {
val result = viewModel.homeUiState.drop(1).first()
assertThat(true).isTrue()
}
@Test
fun flowViewModelTesting2() = runTest {
val result = viewModel.homeUiState.drop(1).first()
assertThat(true).isTrue()
}
}
I'm new at testing, trying to take second flow value and assert it, When i run this test one by one runs fine but when i run whole test once first test runs fine and rest of test give me timeout error.
Error :
After waiting for 60000 ms, the test coroutine is not completing
kotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 60000 ms, the test coroutine is not completing
at app//kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$3$3.invokeSuspend(TestBuilders.kt:304)
(Coroutine boundary)
@OptIn(ExperimentalCoroutinesApi::class)
class HomeViewModelTest {
private lateinit var viewModel: HomeViewModel
private val testDispatcher = UnconfinedTestDispatcher()
@Before
fun setup() {
viewModel = HomeViewModel(FakeOrderRepository())
Dispatchers.setMain(testDispatcher)
}
@After
fun tearDown() {
Dispatchers.resetMain()
testDispatcher.cancel()
}
@Test
fun flowViewModelTesting1() = runTest {
val result = viewModel.homeUiState.drop(1).first()
assertThat(true).isTrue()
}
@Test
fun flowViewModelTesting2() = runTest {
val result = viewModel.homeUiState.drop(1).first()
assertThat(true).isTrue()
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我也有同样的问题。用
standardTestDispatcher()
将解决该问题。I had the same issue. Replacing
UnconfinedTestDispatcher()
withStandardTestDispatcher()
will solve the problem.这也许是因为有一个Coroutine在您的视图模型或他的依赖性(例如存储库)中永无止境。您可以尝试几件事:
我不确定现在在Android Studio上是否可以使用Coroutines调试器,但是如果是,您可以在所有测试功能之后放置一个断点,并使用它来检查哪个Coroutine是哪个Coroutine是仍在运行。
如果您使用的是
coroutinescope(sustaSorjob() + dispatchers.default)
,请检查视图模型及其依赖项。如果是,请确保使用60年代完成的悬挂功能。如果您使用的是myFlow.oneach {}。
不要用测试范围替换外部范围的调度程序(例如
coroutinescope(sustepisorjob() + mytestDisPatcher)
)),否则,测试执行将阻止执行您的暂停功能和执行悬挂功能只有在测试结束后才会返回,这可能会导致这种无限的测试行为或如果您进行仪器测试,则会卡住屏幕。另外,将范围和调度器放在构造函数上,因此在测试中,您可以控制使用哪个。This is maybe because there is a coroutine that never ends in your view model or in his dependencies (like the repository). There is a couple of things you can try:
I am not sure if coroutines debugger is available on Android Studio right now, but if it is you can put a breakpoint after all your test functions and use it to check which coroutine is still running.
Check in your view model and its dependencies if you are using an external scope like
CoroutineScope(SupervisorJob() + Dispatchers.Default)
. If you are, make sure you are using with a suspend function that finishes in 60s. If you are using to observe a value like inmyFlow.onEach{}.launchIn(externalScope)
it may be that because the job is still running.Don't replace the dispatchers of your external scope with the test scope (like in
CoroutineScope(SupervisorJob() + myTestDispatcher)
), otherwise the test execution will block the execution of your suspend functions and the suspend function will only return after your test is over, which may cause this infinite testing behavior or a screen being stucked if you are making instrumented tests. Also, put your scopes and dispatchers on the constructor, so in tests you can control which one is being used.就我而言,我只需要在流动过程中所要求的函数中所需的嘲笑参数。
在这里,我忘了在
function2
中模拟bannerkey
,这解决了此问题。In my case, I just was required to mockk parameters that were required in the functions I called during the flow.
Here I had Forgot to mock
bannerKey
inFunction2
,that resolved this issue.如果您使用的是Kotlinx-coroutines-Test-JVM:1.7或更高版本,则可以作为参数传递超时。默认参数为10秒。
因此,您可以将参数添加到
runtest
If you are using kotlinx-coroutines-test-jvm:1.7 or higher you can pass the timeout as an argument. The default argument is 10 seconds.
So you can add the argument to
runTest
此错误的大多数时间原因是您尚未完成观察者变量调用。
在测试案例呼叫的结尾处
finish()
方法在您的观察者变量上。Most of the time reason for this error is that you have not finish your observer variable call.
At the end of your test case call
finish()
method on your observer variable.您不使用
testDisPatcher
。您应该将其传递给runtest
喜欢:https://developer.android.android.android.android.android .com/kotlin/coroutines/test
You're not using the
testDispatcher
. You should pass it torunTest
like:https://developer.android.com/kotlin/coroutines/test
当您使用runtest时,您默认使用
standardTestDisPatcher
,这意味着它不会立即运行。您必须从一直使用的视图模型
替换
的
同一调度程序中启动测试,请尝试一下。如果不检查您的ViewModel代码,我不能分享太多。
When you use runTest, so you're using
StandardTestDispatcher
by default that means it won't immediately run.You have to launch your test from the same dispatcher that you have been using for a ViewModel
Replace
with
it should work, give it a try. I can't share much without checking your viewmodel code.
所有这些答案都是错误的,您正在寻找
dispatchTimeOutms
:通常,您应该尝试使测试运行更快或测试较小的事物,但是我需要每次一次这样做。
All of these answers are wrong, you are looking for
dispatchTimeoutMs
:Normally, you should try to make your test run faster, or test smaller things, but I have needed to do this from time-to-time.