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

Android Kotlin中用Mockk测试工具类时遇MockKException错误求助

解决MockK测试中「Missing mocked calls inside every { ... } block」错误

错误原因

你试图mock真实的TestApp实例的方法,但MockK的every {}语法仅能作用于MockK创建的mock/spy对象,真实对象的方法调用无法被MockK拦截,因此触发该错误。

你的代码问题点

  • private val testApp = TestApp(mockk(relaxed = true)):创建的是TestApp的真实实例,而非MockK代理的mock/spy对象,导致every {}无法生效。
  • 构造TestApp时未使用已定义的context变量,属于冗余代码。
  • MockkAnnotaions.init拼写错误(正确为MockkAnnotations.init),且relaxUnion参数不存在,应为relaxUnitFun = true。
  • Build.VERSION.RELEASE返回类型是String,测试中用return 11会存在类型不匹配问题。

修复方案

方案一:用Spy对象Mock指定方法

如果需要mockgetOSNumber()的返回值,不需要执行真实逻辑,可以用spyk包装真实实例,既能保留对象原有行为,又能单独mock目标方法:

class TestAppTest {

    private val context = mockk<Context>(relaxed = true)
    private lateinit var testApp: TestApp

    @Before
    fun setup() {
        MockkAnnotations.init(this, relaxUnitFun = true)
        testApp = spyk(TestApp(context)) // 用spyk包装真实实例
    }

    @Test
    fun testOs() {
        // Mock getOSNumber方法的返回值(注意是String类型)
        every { testApp.getOSNumber() } returns "11"

        val number = testApp.getOSNumber()

        assertEquals("11", number)
    }
}

方案二:用Robolectric测试真实逻辑

如果要验证getOSNumber()的真实逻辑(返回系统版本号),由于Build.VERSION是Android框架类,本地单元测试无法直接获取真实值,需用Robolectric模拟Android环境:

  1. 添加Robolectric依赖(build.gradle.kts):
testImplementation("org.robolectric:robolectric:4.12.1")
  1. 编写测试代码:
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [30]) // 指定模拟的Android SDK版本(对应Android 11)
class TestAppTest {

    private val context = ApplicationProvider.getApplicationContext<Context>()
    private val testApp = TestApp(context)

    @Test
    fun testOs() {
        val number = testApp.getOSNumber()
        assertEquals("11", number) // Robolectric会返回指定SDK的版本号
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:12:25