我正在尝试使用该mockk
框架在我的一个单元测试中设置一个模拟,该单元测试执行如下挂起函数:
val executionCompletionSource = CompletableDeferred<Nothing>()
suspend fun task(): Unit = executionCompletionSource.await()
val mock = mockk<Executable> { coEvery { execute() } coAnswers { task() } }
mock.execute()
但是,如果我在启动的协程范围内调用,我发现测试会无限期挂起。如果我task()
直接在启动范围内调用,则测试运行良好。
尽管mockk 文档确实谈到了一些关于 coroutine mocking 的内容,但我找不到任何文档或示例来展示如何执行 coroutines 以响应在 mock 上调用挂起函数。
这是一个 SSCCE 展示了这一点:
package experiment
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.system.measureTimeMillis
interface Executable {
suspend fun execute()
}
fun main() {
val executionCompletionSource = CompletableDeferred<Nothing>()
suspend fun task(): Unit = executionCompletionSource.await()
val mock = mockk<Executable> { coEvery { execute() } coAnswers { task() } }
runBlocking {
val execution = launch { mock.execute() } // This blocks the test indefinitely
//val execution = launch { task() } // This works fine (~110-120 ms)
measureTimeMillis {
delay(100)
executionCompletionSource.cancel()
execution.join()
}.also { elapsed -> println("Elapsed in $elapsed ms") }
}
}
使用以下依赖项:
implementation(kotlin("stdlib-jdk8"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0")
implementation("io.mockk:mockk:1.8.10.kotlin13")