You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito测试继承方法遇阻:子类调用父类方法如何Mock?

解决方案:Mock父类A的someMethod方法

问题分析

你的两种方案未能生效的原因:

  1. Spy方案:你使用了精确参数匹配,但someMethodFromB调用someMethod时传入的参数(比如someAnotherObj)和你mock时的obj并非同一实例,导致mock规则不匹配,无法拦截调用。
  2. @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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 03:42:36