You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin协程中获取可测试的虚拟时间戳?

可测试的协程时间戳获取方案

要实现一个在生产环境和runTest测试中都能正确工作的时间戳获取函数,核心是从当前协程上下文的调度器中获取时间,而非硬编码系统时间或测试专属的currentTime。以下是具体实现:

实现代码

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.ContinuationInterceptor
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Test
import kotlin.test.assertThat
import kotlin.test.assertEquals

suspend fun getCurrentTime(): Long {
    // 从协程上下文获取当前调度器
    val dispatcher = coroutineContext[ContinuationInterceptor] as CoroutineDispatcher
    return when (dispatcher) {
        // 测试环境下使用TestDispatcher的可控虚拟时间
        is TestDispatcher -> dispatcher.currentTime
        // 生产环境下使用系统真实时间
        else -> System.currentTimeMillis()
    }
}

@Test
fun testMyCode() = runTest {
    delay(20)

    assertThat(this.currentTime).isEqualTo(20)
    assertThat(getCurrentTime()).isEqualTo(20)
}

原理说明

  • 生产环境:协程默认使用Dispatchers.Default等标准调度器,函数会返回System.currentTimeMillis(),符合正常业务逻辑需求。
  • 测试环境:runTest会自动将协程上下文替换为TestDispatcher(如StandardTestDispatcher),该调度器的currentTime属性与TestScope.currentTime完全同步,能精准反映测试中的虚拟时间推进,不会被delay的跳过逻辑影响。

关于废弃的DelayController

DelayController被废弃后,官方推荐直接使用TestDispatcher的currentTime属性获取虚拟时间,这是当前测试协程时间的标准方式,无需再依赖废弃API。

内容的提问来源于stack exchange,提问作者Ajmal Kunnummal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 16:25:08