Mik*_*ler 5 executorservice kotlin kotlinx.coroutines
我们最近开始在我们的 Android 应用程序上使用协程。一切都很顺利,直到有人写了一些大致相当于以下函数的东西:
fun example(dispatcher: CoroutineDispatcher, block: () -> Unit) {
launch(dispatcher) {
block()
}
}
Run Code Online (Sandbox Code Playgroud)
我们想编写一个测试来验证block使用dispatcher.
我们已经尝试了以下方法,但这不起作用,因为我们得到了一个 NullPointerException,因为dispatcher.parentContext它没有被模拟。我不愿意嘲笑它,因为我们不关心它在什么上下文中执行,只关心它是如何执行的:
@Test
fun `test that doesn't work`() {
val dispatcher: CoroutineDispatcher = mock()
val block: () -> Unit = mock()
// fails here, specifically on the call to `launch` in example()
example(dispatcher, block)
val captor = argumentCaptor<Runnable>()
verify(dispatcher).dispatch(any(), captor.capture())
verify(block, never()).invoke()
captor.firstArgument.run()
verify(block).invoke()
}
Run Code Online (Sandbox Code Playgroud)
我们已经将此作为一种选择,但仍然感觉不对:
@Test
fun `test that works but doesn't feel right`() {
val executor: ExecutorService = mock()
val block: () -> Unit = mock()
example(executor.asCoroutineDispatcher(), block)
val captor = argumentCaptor<Runnable>()
verify(executor).execute(captor.capture())
verify(block, never()).invoke()
captor.firstArgument.run()
verify(block).invoke()
}
Run Code Online (Sandbox Code Playgroud)
谁能想出更好的办法?
编辑:
值得注意的依赖如下:
com.nhaarman:mockito-kotlin:1.5.0
org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5
junit:junit:4.12
org.jetbrains.kotlin:kotlin-stdlib:1.2.30
Run Code Online (Sandbox Code Playgroud)
由于launch返回 a Job,您需要等待其完成才能验证已完成的任何操作。
您可以通过两种方式做到这一点:
由于您正在launch使用协程,因此您的实际单元测试可能会在启动执行完成之前完成。您需要等待其执行以确保您的测试不会提前完成。您可以通过多种方式做到这一点。
更改您的函数签名以从启动返回作业(例如fun example(dispatcher: CoroutineDispatcher, block: () -> Unit) = launch(dispatcher) { ...。这样您就可以调用.join()该example函数以等待其完成。
var exampleJob:Job? = null,并使用启动的执行来设置它,例如exampleJob = launch { ...}。这样,在测试中,您可以exampleJob.join()等待其完成并在之后进行验证。奖金解决方案:
您还可以使用MockK进行verifyWithTimeout单元测试。这样,您的单元测试就会等待验证完成。
| 归档时间: |
|
| 查看次数: |
567 次 |
| 最近记录: |