我正在创建一个库,并且我正在使用带有调用适配器的 Retrofit,它给我一个 Deferred 值。在我的代码中的一个函数中,我调用 launch {} ,并在其中调用 try-catch 值和可能的异常 - 为不同的结果调用不同的回调。我在测试协程上找到的资源都是关于测试挂起的函数的,runBlocking {} 是解决所有问题的方法。除了我它不是我做了一个简单的例子 @Mockval mockListener: DoSomething.Listener = mock()@Testfun testSomething() { val doer = DoSomething(mockListener) runBlocking { doer.doIt() verify(mockListener).listen(any()) }}class DoSomething(val listener: Listener) { interface Listener { fun listen(s: String) } fun doIt() { launch { listener.listen(theThing().await()) } } private fun theThing(): Deferred<String> { return async { delay(5, TimeUnit.SECONDS) return@async "Wow, a thing" } }}我想要的是实际运行所有功能。测试最少需要 5 秒,但它只是在几毫秒内运行代码 - 即。它不会阻塞。我试过添加runBlocking { launch { // doer.doIt() }.joinChildren()}和类似的做法,但我只是无法让测试在测试完成之前实际等待我在另一个类中的启动完成。将 verify(...) 放在 runBlocking 之外也会使测试失败,这是应该的。任何输入,助手,良好做法等表示赞赏! 最佳答案 您可以为 doIt() 函数显式提供 CoroutineContext:fun doIt(context: CoroutineContext = DefaultDispatcher) { launch(context) { listener.listen(theThing().await() }}使用此参数,您可以轻松更改协程上下文 - 在您的测试代码中,您可以使用阻塞上下文:runBlocking { doer.doIt(coroutineContext)}顺便说一句:您不需要使用 launch 和 async 。使用 launch 您处于 suspendable 上下文中,并且不需要异步运行 theThing()。特别是如果您在下一步中调用 await() :fun doIt(context: CoroutineContext = DefaultDispatcher) { launch(context) { listener.listen(theThing()) }}private suspend fun theThing(): String { delay(5, TimeUnit.SECONDS) return "Wow, a thing"}关于android - 如何在函数内测试 Kotlin 协程?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51855919/
10-13 03:00