Mockito测试继承方法遇阻:子类调用父类方法如何Mock?
解决方案:Mock父类A的someMethod方法
问题分析
你的两种方案未能生效的原因:
- Spy方案:你使用了精确参数匹配,但
someMethodFromB调用someMethod时传入的参数(比如someAnotherObj)和你mock时的obj并非同一实例,导致mock规则不匹配,无法拦截调用。 - @Mock A + @InjectMocks B方案:
@InjectMocks仅用于向被测试类注入依赖对象,无法替换子类继承自父类的方法实现。B实例会直接使用自身继承的someMethod,和你mock的A对象没有关联。
可行方案一:使用Mockito Spy + 正确参数匹配
如果someMethod的参数在someMethodFromB中经过转换,你需要用参数匹配器确保mock能匹配到实际调用:
@Test public void testSomeMethodFromB() throws Exception { ContextData contextData = mock(ContextData.class); SomeObject obj = mock(SomeObject.class); // 创建B的spy对象,保留真实对象的大部分行为 B b = spy(new B()); // 使用参数匹配器,适配实际调用的参数 doReturn(obj).when(b).someMethod(any(SomeObject.class), eq(contextData), eq(false)); // 执行测试方法 SomeObject result = b.someMethodFromB(someAnotherObj, contextData, Optional.of("someString")); Assert.assertNotNull(result); Assert.assertEquals(obj, result); }
核心注意事项:
- 必须用
doReturn(...).when(spyObj).method(...)语法,而非when(spyObj.method(...)).thenReturn(...)——后者会触发真实方法执行,可能引发意外逻辑。 - 根据实际场景选择匹配器:需要精确匹配用
eq(),不关心具体实例用any()。
可行方案二:使用PowerMock模拟父类方法(复杂场景)
如果someMethod是final/static方法,或需要完全覆盖父类行为,可使用PowerMock:
1. 添加PowerMock依赖(Maven示例)
<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency>
2. 编写测试用例
@RunWith(PowerMockRunner.class) @PrepareForTest(B.class) // 声明需要处理的子类 public class BTest { @Test public void testSomeMethodFromB() throws Exception { ContextData contextData = mock(ContextData.class); SomeObject obj = mock(SomeObject.class); B b = new B(); // 直接mock父类A的someMethod方法 PowerMockito.doReturn(obj).when(b, "someMethod", any(SomeObject.class), eq(contextData), eq(false)); SomeObject result = b.someMethodFromB(someAnotherObj, contextData, Optional.of("someString")); Assert.assertNotNull(result); Assert.assertEquals(obj, result); } }
核心注意事项:
- 必须添加
@RunWith(PowerMockRunner.class)和@PrepareForTest(B.class)注解,让PowerMock能够修改子类的字节码。 - 使用
PowerMockito.doReturn(...).when(对象, "方法名", 参数匹配器)语法指定要mock的父类方法。
内容的提问来源于stack exchange,提问作者Mohd Abdul Azeem
相关产品推荐
相关产品推荐

