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

Mockito无法模拟目标类构造函数内的方法调用问题求助

我能理解你折腾一天的崩溃感,Mockito的Spy和方法桩化确实有不少容易踩的坑,咱们一步步来解决你的问题:

问题分析与修正方案

你的核心问题出在Spy的使用方式和方法桩化的时机&语法错误上,导致桩化的makeNewObject方法没有生效,构造器仍然调用了真实方法,进而引发空指针异常。

具体错误点:

  • 桩化语法错误:
    makeNewObject是实例方法不是静态方法,你写的when(A.makeNewObject)写法完全错误,必须针对A的Spy实例来桩化;另外when(someObject.doSomething)缺少方法调用的括号,正确写法是when(someObject.doSomething()).thenReturn(...)。
  • Spy桩化逻辑错误:
    用when(a.makeNewObject(...)).thenReturn(...)这种语法操作Spy时,会先执行一次真实的makeNewObject方法再做桩化,而你的构造器在创建对象时就调用了这个方法,直接触发了真实方法的执行导致空指针。正确做法是用doReturn(...).when(a).makeNewObject(...),这种方式不会执行真实方法。
  • 初始化顺序错误:
    你需要在创建A的实例之前完成makeNewObject的桩化,但代码里先创建了A实例再桩化,完全搞反了顺序。
  • 变量命名笔误:
    代码里this.A = new A(...)是错误的,变量名应该对应你定义的@Spy A a;,写成this.a = ...。

修正后的测试代码

@RunWith(MockitoJUnitRunner.class)
public class ATest {
    @Mock 
    SomeImpClass someImpObject1; // 注意修正原代码里类名不一致的问题
    @Mock 
    SomeImpClass2 someImpObject2;
    @Mock 
    SomeClass someObject; // 与类A中的成员变量类型保持一致

    @Spy
    A a;

    @Before
    public void setUp() {
        // 1. 先桩化makeNewObject方法,用doReturn避免执行真实逻辑
        doReturn(someObject).when(a).makeNewObject(someImpObject1, someImpObject2);
        // 2. 再创建A的实例
        a = new A(someImpObject1, someImpObject2);
        // 3. 桩化someObject的doSomething方法
        when(someObject.doSomething()).thenReturn("something"); // 替换为你实际需要的返回值
    }

    // 示例测试用例
    @Test
    public void testUsingSomeObject() {
        a.usingSomeObject();
        // 验证mock对象的方法是否被正确调用
        verify(someObject).doSomething();
    }
}

额外注意事项:

  • 类A中的makeNewObject方法必须是非private的(比如protected、包访问权限或public),因为Mockito无法桩化private方法。如果必须用private,建议重构代码把该逻辑抽离到单独类中,或者使用PowerMock扩展工具。
  • 一定要保证测试代码和被测试代码的类名、方法签名完全一致,避免因笔误导致的编译或逻辑错误。

内容的提问来源于stack exchange,提问作者Kartavya Ramnani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:22:19