如何用PowerMockito模拟子类未重写的抽象父类方法?
解决PowerMockito模拟子类未重写父类方法的问题
这个问题我之前也碰到过——普通Mockito确实没法直接mock子类没重写的父类方法,因为它只会处理子类自身定义的方法,继承来的方法调用会直接走到父类的真实实现里。要解决这个问题,得靠PowerMockito的字节码修改能力,具体步骤如下:
1. 配置测试类注解
首先,你的测试类需要加上PowerMockito的运行器和@PrepareForTest注解,这个注解是关键——它告诉PowerMockito要修改哪个类的字节码,这里我们指定子类ChildClass,因为要拦截它继承的父类方法调用:
@RunWith(PowerMockRunner.class) @PrepareForTest(ChildClass.class) public class YourTestClassName { // 测试方法写在这里 }
2. 使用PowerMockito的mock/Spy + doReturn来模拟方法
普通的when(child.method()).thenReturn(...)会先触发一次真实的父类方法调用,推荐用doReturn的方式来避免这个问题,同时确保模拟生效:
方式一:完全mock子类(所有方法都被模拟)
@Test public void testMockParentMethod() { ChildClass child = PowerMockito.mock(ChildClass.class); // 指定父类method()的返回值 PowerMockito.doReturn("my mock string").when(child).method(); System.out.println(child.method()); // 输出:my mock string }
方式二:Spy子类(保留子类自身方法的真实逻辑,只mock父类方法)
如果你的子类start()方法有真实实现,需要保留它的行为,只mock父类的method(),可以用Spy:
@Test public void testSpyParentMethod() { ChildClass child = PowerMockito.spy(new ChildClass()); PowerMockito.doReturn("my mock string").when(child).method(); System.out.println(child.method()); // 输出:my mock string // 调用child.start()会走真实的实现(如果有的话) }
原理说明
PowerMockito和普通Mockito的核心区别在于它能修改类的字节码。通过@PrepareForTest(ChildClass.class),PowerMockito会改写子类的字节码,让它继承的父类方法调用被拦截,从而替换成我们指定的模拟返回值,而不是执行父类的真实方法。
内容的提问来源于stack exchange,提问作者hongchangfirst
相关产品推荐
相关产品推荐

