升级Target SDK至34后MockK静态Mock Log类出现匹配失败异常
解决Target SDK 34下MockK静态Mock Log类的匹配失败问题
问题概述
单元测试在Target SDK 28环境下可正常通过,升级至SDK 34后,MockK静态Mock Log类时出现方法签名匹配失败异常。
相关代码
测试类代码
val TAG = Logging.tag<MyClass>() @Before fun setUp() { MockKAnnotations.init(this, relaxUnitFun = true) activitySwitchManagerUtil = ActivitySwitchManagerUtil(activityManager, activitySwitchObserverUtil) mockkStatic(Log::class) every { Log.d(any(), any()) } returns 0 every { Log.i(any(), any()) } returns 0 every { Log.e(any(), any()) } returns 0 } @Test fun `test 1`() { // ... 测试逻辑 verify { Log.i(TAG, "Registered Activity Switch Observer") } }
Logging工具类代码
object Logging { inline fun <reified T : Any> tag(): String { return "$applicationName::${T::class.simpleName}" } }
异常信息
io.mockk.MockKException: Failed matching mocking signature for left matchers: [any(), any()] at io.mockk.impl.recording.SignatureMatcherDetector.detect(SignatureMatcherDetector.kt:99) at io.mockk.impl.recording.states.RecordingState.signMatchers(RecordingState.kt:38) at io.mockk.impl.recording.states.RecordingState.round(RecordingState.kt:30) at io.mockk.impl.recording.CommonCallRecorder.round(CommonCallRecorder.kt:45) at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:47) at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:25) at io.mockk.MockKDsl.internalEvery(API.kt:93) at io.mockk.MockKKt.every(MockK.kt:104) at com.company.app.util.MyClassTest.setUp(MyClassTest.kt:37) at java.base@17.0.12/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.12/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.12/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.12/java.lang.reflect.Method.invoke(Method.java:569) at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:52) at app//org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) at app//org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:489) at app//org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:291) at app//org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:104) at java.base@17.0.12/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base@17.0.12/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base@17.0.12/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base@17.0.12/java.lang.Thread.run(Thread.java:840)
当前环境
target sdk = 34 MockK = 1.8.10 Robolectric = 4.12.2 JDK17 = 1.0
已尝试的无效写法
every { Log.d(any<String>(), any<String>()) } returns 0 every { Log.d(TAG, any<String>()) } returns 0 every { Log.d(TAG, "test") } returns 0
解决方案
方案1:升级MockK版本(推荐)
MockK 1.8.10版本对Android 14(SDK34)的系统类静态方法重载匹配存在兼容性问题,升级至1.13.8或更高稳定版本即可解决。修改项目依赖:
// 单元测试依赖 testImplementation "io.mockk:mockk:1.13.8" // 仪器化测试依赖(如果需要) androidTestImplementation "io.mockk:mockk-android:1.13.8"
升级后原有的every { Log.d(any(), any()) } returns 0写法可正常运行。
方案2:使用Relaxed静态Mock
在调用mockkStatic时添加relaxed = true参数,让MockK自动匹配所有Log类的静态方法重载,并返回对应类型的默认值(int类型默认返回0),无需手动编写every语句:
mockkStatic(Log::class, relaxed = true)
方案3:明确匹配所有方法重载(不推荐)
如果无法升级版本,需手动指定匹配Log类的所有相关方法重载,包括带Throwable参数的版本:
// Mock两个参数的重载 every { Log.d(any<String>(), any<String>()) } returns 0 every { Log.i(any<String>(), any<String>()) } returns 0 every { Log.e(any<String>(), any<String>()) } returns 0 // Mock带Throwable的三个参数重载 every { Log.d(any<String>(), any<String>(), any<Throwable>()) } returns 0 every { Log.i(any<String>(), any<String>(), any<Throwable>()) } returns 0 every { Log.e(any<String>(), any<String>(), any<Throwable>()) } returns 0
内容的提问来源于stack exchange,提问作者enjoinslip
相关产品推荐
相关产品推荐

