PowerMockito Spy调用真实方法报错:CannotStubVoidMethodWithReturnValue
解决PowerMockito Spy测试void方法时的"CannotStubVoidMethodWithReturnValue"错误
这个问题的核心是mock私有方法时的语法错误,导致PowerMockito误将你调用真实void方法的操作当成了试图给它存根返回值的操作。咱们一步步来修复:
问题根源
看你的测试代码,mock私有方法那一行存在两个关键问题:
PowerMockito.doReturn(deviceObject).`when`(testedRepo, PowerMockito.method(MyClass::class.java, "getDeviceObject"))
- 对象引用错误:你spy的实例是
myClassTest,但这里写了testedRepo,PowerMockito找不到正确的目标对象,进而引发语法误解。 - 语法冗余且易出错:使用
PowerMockito.method()的写法没必要,直接指定方法名的重载写法更简洁可靠。
修复步骤
1. 修正私有方法的mock语法
把mock私有方法的代码改成下面这样,确保目标是你创建的spy实例myClassTest:
// 正确mock私有方法:指定spy实例+方法名 PowerMockito.doReturn(deviceObject).`when`(myClassTest, "getDeviceObject")
你也可以用另一种等价的简洁写法:
PowerMockito.when(myClassTest, "getDeviceObject").thenReturn(deviceObject)
这两种写法都能让私有方法getDeviceObject返回你预先创建的mock对象deviceObject。
2. 直接调用真实方法即可
spy对象默认会调用真实方法,你调用myClassTest.persistDeviceData(DeviceInfo(), a)时不需要额外添加doCallRealMethod()存根,直接调用就行。
完整修正后的测试代码
import io.kotlintest.KTestJUnitRunner import io.kotlintest.specs.BehaviorSpec import org.junit.Assert.assertTrue import org.junit.runner.RunWith import org.powermock.api.mockito.PowerMockito import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunnerDelegate @RunWith(PowerMockRunner::class) @PowerMockRunnerDelegate(KTestJUnitRunner::class) @PrepareForTest(MyClass::class) class MyClassTest: BehaviorSpec(){ init { val deviceObject = PowerMockito.mock(MyDeviceObject::class.java) val myClassTest = PowerMockito.spy(MyClass()) // 修正后的私有方法mock逻辑 PowerMockito.doReturn(deviceObject).`when`(myClassTest, "getDeviceObject") val a = SaveCallback { // Callback handling here } // 直接调用spy的真实void方法 myClassTest.persistDeviceData(DeviceInfo(), a) assertTrue(true) } }
额外注意事项
- 确保
@PrepareForTest(MyClass::class)注解正确添加,PowerMockito需要修改该类的字节码才能mock私有方法。 - 如果
MyDeviceObject是final类,需要把它也加入@PrepareForTest参数中,比如@PrepareForTest(MyClass::class, MyDeviceObject::class),否则PowerMockito无法mock这个类。
内容的提问来源于stack exchange,提问作者Alexandr Zhurkov
相关产品推荐
相关产品推荐

