【问题标题】:Why are delays skipped in a Kotlin Flow inside a test?为什么在测试中的 Kotlin Flow 中会跳过延迟?
【发布时间】: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


【解决方案1】:

runTest() 默认情况下会为您跳过任何延迟()。

【讨论】:

    猜你喜欢
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2021-01-15
    • 2011-05-06
    • 1970-01-01
    相关资源
    最近更新 更多