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

如何使用Mockito对私有方法内声明的类实例进行Mock

私有方法内部硬编码实例的Mock解决方案

核心思路:由于你要测试的私有方法内部直接通过new ClassName()硬编码生成实例,普通Mock框架无法拦截实例化过程,需要搭配具备构造函数拦截能力的Mock工具,配合现有WhiteBox API调用私有方法即可实现需求。

方案1:PowerMock + WhiteBox(兼容JUnit4)

  • 首先添加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>
  • 测试类添加必要注解:
@RunWith(PowerMockRunner.class)
// 此处填写你私有方法所在的类、以及要拦截构造的ClassName
@PrepareForTest({TargetClass.class, ClassName.class})
public class TargetClassTest {
}
  • 测试方法逻辑:
@Test
public void testGetFunctReturn() throws Exception {
    // 1. 初始化待测试类实例
    TargetClass testInstance = new TargetClass();
    // 2. Mock ClassName实例,并预设getMap方法返回值
    ClassName mockClassName = Mockito.mock(ClassName.class);
    Map mockMap = new HashMap<>();
    // 自行填充map测试数据
    mockMap.put("k1", "v1");
    Mockito.when(mockClassName.getMap()).thenReturn(mockMap);
    // 3. 拦截无参构造方法,所有new ClassName()调用都会返回上面的mock实例
    PowerMockito.whenNew(ClassName.class).withNoArguments().thenReturn(mockClassName);
    // 4. 用WhiteBox调用私有方法,此时内部生成的就是你Mock的实例
    Object result = Whitebox.invokeMethod(testInstance, "getFunctReturn");
    // 5. 自定义断言逻辑
    Assert.assertNotNull(result);
}

方案2:Mockito原生构造Mock(兼容JUnit5,无需PowerMock)

如果使用Mockito 3.5+版本,可以用原生mockConstruction方法拦截构造调用,无需引入PowerMock:

@Test
public void testGetFunctReturn() {
    TargetClass testInstance = new TargetClass();
    Map mockMap = new HashMap<>();
    mockMap.put("k1", "v1");
    // 拦截ClassName的所有构造调用,统一预设返回值
    try (MockedConstruction<ClassName> mockedConstruction = Mockito.mockConstruction(ClassName.class,
            (mock, context) -> Mockito.when(mock.getMap()).thenReturn(mockMap))) {
        // 调用私有方法,内部new的ClassName全为Mock实例
        Object result = Whitebox.invokeMethod(testInstance, "getFunctReturn");
        // 断言逻辑
        Assert.assertNotNull(result);
        // 可选:验证构造方法调用次数
        Assert.assertEquals(1, mockedConstruction.constructed().size());
    }
}

注意:如果使用的WhiteBox是Spring提供的ReflectionTestUtils,只需把调用私有方法的代码替换为ReflectionTestUtils.invokeMethod(testInstance, "getFunctReturn")即可,Mock逻辑完全通用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 20:12:01