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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:45:17