【发布时间】:2020-11-06 13:04:38
【问题描述】:
当我执行这个单元测试时,我在输出中看到异常通知(可能是默认异常处理程序打印它):
@Test
fun uncaughtException() {
runBlocking {
val scope = CoroutineScope(Dispatchers.Default)
val job = scope.launch() {
delay(100)
println("inside coroutine")
}
scope.launch {
delay(50)
throw Exception()
}
job.join()
}
Thread.sleep(100)
println("test completed")
}
然后我尝试将我的自定义 CoroutineExceptionHandler 添加到范围的上下文中:
@Test
fun exceptionHandler() {
runBlocking {
val exceptionHandler = CoroutineExceptionHandler { _, throwable -> {
println("Caught exception")
}}
val scope = CoroutineScope(Dispatchers.Default + exceptionHandler)
val job = scope.launch() {
delay(100)
println("inside coroutine")
}
scope.launch {
delay(50)
throw Exception()
}
job.join()
}
Thread.sleep(100)
println("test completed")
}
这使得先前关于异常的消息消失(这可能意味着我的自定义处理程序替换了默认处理程序),但是我的自定义处理程序的 handleException() 没有被调用,并且我在输出(仅“测试完成”)。
我认为这可能与单元测试有关,所以我在 Android 应用程序中尝试了相同的代码。结果是一样的:出现异常时应用程序不会崩溃(这意味着默认处理程序已被替换),但我的自定义处理程序的 handleException() 函数没有被调用。
这感觉不对。这是预期的行为还是错误?
【问题讨论】:
-
调试过程中会发生什么?或者更好地说,当你在
printLn()中放置断点时@ -
@coroutineDispatcher,它既不会在测试中触发,也不会在生产代码中触发。
-
如果有影响,你能用
runBlockingTest试试吗? -
@coroutineDispatcher,正如我所写,这种行为会在真正的 Android 应用程序中重现,所以我认为它与“测试”东西没有任何关系