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

如何在Kotlin中Mock Handler?Slot未初始化报错求助

问题解决:MockK Slot捕获Runnable时"lateinit property captured has not been initialized"错误

错误原因

你代码的核心问题是执行顺序颠倒:在调用Manager.myTesting()触发Handler的postDelayed方法之前,就尝试访问slotrunnable.captured,此时Slot还没有捕获到任何Runnable实例,自然会抛出未初始化的异常。

另外你的Handler Mock逻辑也存在问题:原代码是通过new Handler(Looper.getMainLooper())创建新的Handler实例,你直接mock一个Handler对象的话,原代码里的新Handler不会使用这个mock实例,导致Slot根本无法捕获调用。

修正后的完整测试代码

// 1. 声明Runnable类型的Slot
val slotRunnable = slot<Runnable>()

// 2. Mock Looper相关逻辑
mockkStatic(Looper::class)
val looper = mockk<Looper> {
    every { thread } returns Thread.currentThread()
}
every { Looper.getMainLooper() } returns looper

// 3. Mock Handler的构造方法,让原代码创建的Handler使用mock实例
val mockHandler = mockk<Handler>(relaxed = true)
mockkConstructor(Handler::class)
every { anyConstructed<Handler>().postDelayed(capture(slotRunnable), 100) } answers { true }

// 4. 先执行目标方法,触发postDelayed调用,让Slot捕获Runnable
Manager.myTesting()

// 5. 此时Slot已捕获到Runnable,再执行run()
slotRunnable.captured.run()

关键修正点

  • 调整执行顺序:必须先调用Manager.myTesting(),让原代码中的Handler触发postDelayed,Slot才能捕获到传入的Runnable,之后才能安全访问captured属性。
  • 正确Mock Handler构造:使用mockkConstructor(Handler::class)来拦截Handler的构造,确保原代码中new Handler(...)创建的实例是我们的mock对象,这样才能捕获到postDelayed的调用。
  • 确保Slot实例正确初始化:显式创建slot<Runnable>()实例,避免未初始化的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:52:07