【发布时间】:2022-08-19 18:00:04
【问题描述】:
提供一点上下文:我正在尝试测试一个内部有延迟的流程。为了很好地测试它,我想在特定时间断言值,因此我必须控制虚拟时间。但是,delay(...) 似乎在测试中被跳过。举个例子:
@Test
fun test(dispatcher: TestDispatcher) = runTest(dispatcher) {
flow {
emit(1)
delay(10000)
emit(2)
}
.flowOn(dispatcher)
.test {
assertEquals(1, awaitItem())
assertEquals(2, awaitItem())
awaitComplete()
}
}
在示例中,我希望 assertEquals(2, awaitItem()) 超时,因为 advanceTimeBy(10001) 没有被调用以超过延迟。但是,此测试成功完成,因此它只是跳过延迟。
有人知道这是为什么吗?我如何实现我想要的?
附言
TestDispatcher 是一个由 JUnit5 扩展提供的StandardTestDispatcher,它在测试前也会调用Dispatchers.setMain。流上的.test { } 来自Turbine 库。本示例使用的版本:
- 科特林:1.6.21
- Kotlin 协程:1.6.1
- 涡轮机:0.8.0
- JUnit5:5.8.2
聚苯乙烯
仅使用协程,行为就符合预期。举个例子。如果您删除 advanceTimeBy,测试将不再有效。
@Test
fun coroutineTest(dispatcher: TestDispatcher) = runTest(dispatcher) {
var number = 0
launch {
number = 1
delay(10_000)
number = 2
}
advanceTimeBy(10_001)
assertEquals(2, number)
}
-
我希望第二个
awaitItem()调用会导致流程等待延迟。它的定义行为是暂停直到下一个项目到达,不是吗?此测试是否在 10 秒内完成? -
是的,它会在几毫秒内完成
标签: unit-testing kotlin kotlin-coroutines kotlin-flow