Mockito mock方法触发InvocationTargetException且GpFun2 mock失败排查
问题原因及解决方案
核心问题分析
你的代码存在两个关键问题,直接导致mock失效和断言错误:
1. Mock对象的方法行为误解
你创建的tgpp是Mock对象,在Mockito中,Mock对象的所有方法默认不会执行真实逻辑,只会返回对应类型的默认值(int类型默认返回0)。当调用t.fun(4)时,实际执行的是tgpp.GpFun(4),这个Mock方法直接返回0,根本不会触发真实的GpFun方法逻辑,自然也不会调用你mock的GpFun2(),所以断言的-5永远不会出现。
2. Stub语句的异常触发(InvocationTargetException)
执行when(tgpp.GpFun2()).thenReturn(-5)时,Mockito的when语法会先调用一次GpFun2()方法。出现异常大概率是因为PowerMock配置冗余:你给@PrepareForTest传入了Thing.class,但实际不需要处理这个类,而且你的场景完全不需要PowerMock,普通Mockito就能搞定。
修复方案
根据你的测试目标,提供两种可行的修复方式:
方式一:用Spy对象保留真实方法逻辑
如果想验证GpFun调用GpFun2的完整逻辑,需要用@Spy代替@Mock,让GpFun执行真实逻辑,同时mockGpFun2的返回值:
@RunWith(MockitoJUnitRunner.class) // 移除PowerMock,用普通Mockito即可 public class ThingTest { @Spy ThingGrandParent tgpp = new ThingGrandParent(); // Spy需要基于真实实例创建 @InjectMocks Thing t; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void test1() throws Exception { // 对Spy对象的方法Stub时,推荐用doReturn语法,避免触发真实方法调用 doReturn(-5).when(tgpp).GpFun2(); assertEquals(-5, t.fun(4)); } }
方式二:直接StubGpFun方法
如果你的测试目标只是验证fun方法能正确返回GpFun的结果,不需要关心GpFun内部逻辑,直接StubGpFun即可:
@RunWith(MockitoJUnitRunner.class) public class ThingTest { @Mock ThingGrandParent tgpp; @InjectMocks Thing t; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void test1() throws Exception { when(tgpp.GpFun(4)).thenReturn(-5); assertEquals(-5, t.fun(4)); } }
额外优化建议
- 移除不必要的PowerMock依赖:你的场景没有涉及静态方法、私有方法等需要PowerMock的特殊逻辑,用普通Mockito更简洁。
- 遵循Java命名规范:方法名改用小驼峰格式(如
gpFun、gpFun2),提升代码可读性。
内容的提问来源于stack exchange,提问作者Pricey
相关产品推荐
相关产品推荐

