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

使用MockK模拟ZonedDateTime.now()抛出MockKException异常求助

解决MockK mock ZonedDateTime.now()抛出Missing mocked calls异常的问题

问题场景

我在用MockK 1.13.5测试一段依赖ZonedDateTime.now()的Kotlin代码时,遇到了io.mockk.MockKException: Missing mocked calls inside every { ... } block异常。测试代码里已经用了mockkStatic(ZonedDateTime::class),但还是报错,换成Mockito-inline可以正常运行,但不想新增依赖。

业务代码

private companion object {
    val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z")
}

fun getSomeValue(): String {
    val dateTime = ZonedDateTime.parse(config.getSomeDateTime(), formatter)
    return if (dateTime < ZonedDateTime.now()) {
        "A"
    } else {
        "B"
    }
}

报错的测试代码

@Test
fun testGetSomeValue() {
    mockkStatic(ZonedDateTime::class) {
        val mockZDT: ZonedDateTime = ZonedDateTime.of(2023, 12, 1, 12, 34, 56, 0, ZoneId.of("UTC"))
        every { ZonedDateTime.now() } returns mockZDT // 此处抛出异常
        every { config.getSomeDateTime() } returns "2023-05-01 01:23:45 UTC"
        service.getSomeValue() shouldBe "A"
    }
}

核心原因与解决办法

  1. MockK对Java静态类的匹配问题
    在MockK 1.13.5版本中,用ZonedDateTime::classmock Java静态类可能存在匹配偏差,换成全限定类名字符串"java.time.ZonedDateTime"调用mockkStatic,能更精准地覆盖Java类的静态方法。

  2. 避免触发未配置的静态mock方法
    你在mockkStatic作用域内调用了ZonedDateTime.of()创建实例,但这个方法也被静态mock了却没有设置返回值,会干扰后续的mock配置逻辑。把实例创建移到mockkStatic块外即可。

修正后的测试代码

@Test
fun testGetSomeValue() {
    // 将ZonedDateTime实例创建移到mock静态块外,避免触发未配置的mock方法
    val mockZDT: ZonedDateTime = ZonedDateTime.of(2023, 12, 1, 12, 34, 56, 0, ZoneId.of("UTC"))
    
    mockkStatic("java.time.ZonedDateTime") {
        every { ZonedDateTime.now() } returns mockZDT
        every { config.getSomeDateTime() } returns "2023-05-01 01:23:45 UTC"
        
        service.getSomeValue() shouldBe "A"
    }
}

备选方案:匹配重载方法

如果上述方案无效,可以尝试mockZonedDateTime.now()的实际调用重载——无参的now()本质是调用now(ZoneId.systemDefault()),直接mock这个带参数的版本也能生效:

@Test
fun testGetSomeValue() {
    val mockZDT: ZonedDateTime = ZonedDateTime.of(2023, 12, 1, 12, 34, 56, 0, ZoneId.of("UTC"))
    
    mockkStatic("java.time.ZonedDateTime") {
        every { ZonedDateTime.now(any<ZoneId>()) } returns mockZDT
        every { config.getSomeDateTime() } returns "2023-05-01 01:23:45 UTC"
        
        service.getSomeValue() shouldBe "A"
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:34:53