PowerMockito中doNothing()调用真实final void方法问题求助
解决PowerMockito模拟final void方法时doNothing()不生效的问题
作为踩过无数PowerMock坑的过来人,太懂你这种明明配置了doNothing()但真实方法还是跑起来的抓狂感了!咱们从最容易踩的几个坑开始排查:
1. 最容易漏掉的核心注解:@PrepareForTest
PowerMock要模拟final方法,必须先修改目标类的字节码,而@PrepareForTest就是告诉它要处理哪个类。如果你的finalVoidMethod()是在Switch类里,那测试类顶部必须加上:
@RunWith(PowerMockRunner.class) @PrepareForTest({Switch.class}) // 必须指定包含final方法的类
别小看这个注解,漏掉它的话,PowerMock根本没法对final方法做手脚,自然会执行真实逻辑。
2. 必须用PowerMockito的方式创建Mock对象
普通Mockito的mock()方法搞不定final方法,你得用PowerMockito提供的创建方式:
// 正确姿势 Switch switchMock = PowerMockito.mock(Switch.class); // 错误姿势(普通Mockito mock,对final方法无效) // Switch switchMock = Mockito.mock(Switch.class);
如果是用@Mock注解注入,记得要配合PowerMock的运行器,同时可以加上@PowerMockIgnore({"javax.management.*"})避免类加载冲突。
3. doNothing()的调用顺序和语法要正确
对final方法的模拟,必须用doNothing().when(mock).method()的顺序,不能像普通方法那样写when(mock.method()).doNothing(),后者对final方法不生效:
// 正确写法 PowerMockito.doNothing().when(switchMock).finalVoidMethod(); // 错误写法(对final方法无效) // Mockito.when(switchMock.finalVoidMethod()).doNothing();
4. 检查版本兼容性
如果上面的都做了还是不行,大概率是PowerMockito和Mockito的版本不匹配。比如PowerMockito 2.x需要搭配Mockito 2.x,PowerMockito 1.x对应Mockito 1.x,版本不对的话会出现各种奇怪的模拟失效问题。
给你贴个完整的正确测试代码示例,对照着检查你的代码:
@RunWith(PowerMockRunner.class) @PrepareForTest(Switch.class) @PowerMockIgnore({"javax.management.*"}) // 避免类加载冲突 public class SwitchWorkerTest { private Switch switchMock; private SwitchWorker switchWorker; @Before public void setUp() { switchMock = PowerMockito.mock(Switch.class); switchWorker = new SwitchWorker(switchMock); } @Test public void testFinalVoidMethodMock() { // 配置mock行为:调用finalVoidMethod时什么都不做 PowerMockito.doNothing().when(switchMock).finalVoidMethod(); // 触发被测试方法,该方法内部会调用switchMock.finalVoidMethod() switchWorker.execute(); // 验证方法确实被调用了(可选,用来确认mock生效) PowerMockito.verify(switchMock).finalVoidMethod(); } }
按照这个流程排查,应该能解决你的问题!
内容的提问来源于stack exchange,提问作者S.Frogile
相关产品推荐
相关产品推荐

