Java转Kotlin后MockK单元测试mockkStatic签名匹配失败如何解决?
问题产生原因
- 静态方法声明不符合JVM规范:Java类中的静态方法自动转换为Kotlin代码后,通常会被放到
companion object代码块中,如果没有额外添加@JvmStatic注解,该方法在JVM层面不属于类的静态方法,mockkStatic(类::class)无法识别匹配到该方法,导致mock逻辑不生效。 - 方法签名匹配错误:从报错栈可以看出,MockK当前匹配到的是父类
TNActivityBase的单参数startActivity(Intent)实例方法,不是你要mock的三参数静态方法,说明实际代码调用时走了原生方法逻辑,触发了host.startActivity(intent)调用,没有命中mock规则。
解决方法
第一步:修正静态方法声明
给目标startActivity方法添加@JvmStatic注解,确保其在JVM层面生成和Java一致的静态方法签名:
class PhoneNumberSelectionActivity : TNActivityBase() { companion object { // 必须添加@JvmStatic注解才能生成类级别静态方法 @JvmStatic fun startActivity( host: Activity, phoneExpired: Boolean, @ACTIVITY_HOST_TYPE activityHostType: Int ) { // 原有方法逻辑保持不变 if (sIsRunning) { return } sIsRunning = true val intent = Intent(host, PhoneNumberSelectionActivity::class.java) intent.putExtra(EXTRA_ACTIVITY_HOST_TYPE, activityHostType) if (phoneExpired) { intent.putExtra(EXTRA_SHOW_PHONE_EXPIRE_DIALOG, true) } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) host.startActivity(intent) } } }
第二步:调整单元测试Mock写法
使用类型更精准的参数匹配器,同时针对Kotlin Unit返回值方法使用更适配的MockK语法:
mockkStatic(PhoneNumberSelectionActivity::class) every { PhoneNumberSelectionActivity.startActivity( eq(mockActivity), // 固定匹配mockActivity参数,也可根据需求用any() anyBoolean(), // 精准匹配布尔类型参数 anyInt() // 精准匹配Int类型参数 ) } just Runs // Kotlin中Unit返回值方法推荐用just Runs替代returns Unit
如果暂时不想修改业务代码加@JvmStatic,也可以直接mock伴生对象类:
// 直接mock伴生对象,不需要修改业务代码 mockkStatic(PhoneNumberSelectionActivity.Companion::class) every { PhoneNumberSelectionActivity.startActivity(any(), anyBoolean(), anyInt()) } just Runs
内容的提问来源于stack exchange,提问作者Kristy Welsh
相关产品推荐
相关产品推荐

