如何使用MockK验证单元测试中的顶层函数是否被调用
MockK 校验顶层(静态)函数调用的正确实现
Kotlin 顶层函数编译后会生成「文件名+Kt后缀」的独立类静态方法,不属于任何实例对象,直接调用verify校验时MockK无法识别未做Mock准备的静态存根,就会抛出io.mockk.MockKException: can't find stub kotlin.Unit异常,按以下步骤实现即可:
- 第一步:提前对顶层函数对应的编译类做静态Mock
如果你的顶层函数定义在Utils.kt文件中,编译后生成的类名为UtilsKt;如果文件加了@file:JvmName("XxxUtils")注解,就用自定义的类名。Mock写法:mockkStatic(UtilsKt::class) - 第二步:对要校验的顶层函数打桩
返回值为Unit的顶层函数必须显式声明返回Unit,如果需要匹配任意参数可以用any(),匹配固定参数直接传入目标值即可:every { someTopLevelFunction("some text") } returns Unit - 第三步:执行触发顶层函数调用的被测业务逻辑
- 第四步:执行原有
verify逻辑完成校验
完整测试用例示例:
import io.mockk.every import io.mockk.mockkStatic import io.mockk.unmockkStatic import io.mockk.verify import org.junit.After import org.junit.Test class BizServiceTest { // 测试结束后清理静态Mock,避免影响其他用例 @After fun tearDown() { unmockkStatic(UtilsKt::class) } @Test fun `verify top level function called correctly`() { // 初始化静态Mock mockkStatic(UtilsKt::class) // 函数打桩 every { someTopLevelFunction("some text") } returns Unit // 执行被测逻辑,替换为实际业务调用 val service = BizService() service.doSomething() // 校验调用 verify { someTopLevelFunction("some text") } } }
注意事项
- 如果不清楚顶层函数对应的编译类名,可以在IDE中右键目标函数选「Copy Reference」,粘贴出的全限定名去掉末尾的方法名就是对应类名。
- 跨模块的顶层函数需要确保测试配置能访问到对应编译类,否则会抛出类找不到异常。
- 静态Mock会全局生效,必须在用例执行完成后做清理,避免污染其他测试用例的运行环境。
内容的提问来源于stack exchange,提问作者georgij
相关产品推荐
相关产品推荐

