使用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" } }
核心原因与解决办法
MockK对Java静态类的匹配问题
在MockK 1.13.5版本中,用ZonedDateTime::classmock Java静态类可能存在匹配偏差,换成全限定类名字符串"java.time.ZonedDateTime"调用mockkStatic,能更精准地覆盖Java类的静态方法。避免触发未配置的静态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
相关产品推荐
相关产品推荐

