有什么方法可以等待示波器中正在运行的挂起函数,例如runBlocking对正在运行的挂起函数做什么?
例如,
class CoroutineTestCase : CoroutineScope {
val job = Job()
var value = 1
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Unconfined
fun testFunction() {
async {
delay(2000)
value = 2
}
}
}
@Test
fun testCoroutine() = runBlocking {
val coroutineTestCase = CoroutineTestCase()
coroutineTestCase.testFunction()
assertEquals(2, coroutineTestCase.value)
}
以上测试失败,值为1且未更改(因为没有等待launch
完成)。如果testFunction
是一个挂起函数,并且我在单元测试中使用runBlocking运行了它,那么一切都会正常进行。
我尝试过与其他自定义调度程序(如下面的调度程序)配合使用,这些调度程序可以阻塞地执行任务,但是没有运气
class TestUiContext : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
block.run()
}
}
答案 0 :(得分:1)
好的,所以我知道了正在发生什么。不等待启动,因为从不使用它的返回值。
在上面的示例中,testFunction
应该返回启动的返回值,该值是可以等待/加入的Deffered对象。因此,要真正等待其完成,必须对代码进行如下更改:
class CoroutineTestCase : CoroutineScope {
val job = Job()
var value = 1
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Unconfined
fun testFunction(): Deferred<Unit> {
return async {
delay(20000)
value = 2
}
}
}
@Test
fun testCoroutine() = runBlocking {
val coroutineTestCase = CoroutineTestCase()
coroutineTestCase.testFunction().await()
assertEquals(2, coroutineTestCase.value)
}
当前唯一的问题是,在这种情况下,它实际上会延迟20秒(使用无限制调度程序)。