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
相关产品推荐
相关产品推荐

