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

如何在不修改类结构的情况下,使用Mockito与JUnit5对新实例中的方法进行Mock?

如何在无法修改类结构时Mock嵌套实例化的SecondClass的secondMethod

你遇到的问题很典型——因为你的代码里ClasstToBeTested直接new FirstClass(),FirstClass又直接new SecondClass(),这种硬编码的对象实例化,普通的Mockito注解(比如@Spy)是没法生效的,因为你Spy的对象和目标类里实际使用的根本不是同一个实例。

要解决这个问题,我们需要用PowerMock来拦截构造函数的调用,把内部new出来的对象替换成我们的Mock实例。下面是具体的实现步骤:

1. 确认依赖(JUnit5版本)

你需要在项目中引入PowerMock的相关依赖,主要包括:

  • powermock-module-junit5:用于JUnit5的扩展支持
  • powermock-api-mockito2:整合Mockito的API

2. 编写测试用例

下面是完整的测试代码,我会逐行解释关键逻辑:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit5.PowerMockExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

// 启用PowerMock的JUnit5扩展
@ExtendWith(PowerMockExtension.class)
// 声明需要被PowerMock处理的类:所有内部有new操作的类都要在这里指定
@PrepareForTest({ClasstToBeTested.class, FirstClass.class})
public class ClasstToBeTestedTest {

    // Mock我们最终要控制的SecondClass
    @Mock
    private SecondClass mockSecondClass;

    @Test
    public void testMethodToBeTested() throws Exception {
        // 第一步:设定Mock对象的行为,让secondMethod返回我们想要的测试值
        when(mockSecondClass.secondMethod()).thenReturn("Mocked Result");

        // 第二步:用PowerMock拦截SecondClass的构造函数
        // 这样每当代码里执行new SecondClass()时,都会返回我们预先Mock好的实例
        PowerMockito.whenNew(SecondClass.class).withNoArguments().thenReturn(mockSecondClass);

        // 第三步:创建待测试类的实例
        ClasstToBeTested testedInstance = new ClasstToBeTested();

        // 第四步:执行测试并验证结果
        String result = testedInstance.methodToBeTested();
        assertEquals("Mocked Result", result);
    }
}

关键逻辑说明

  • @PrepareForTest:必须指定所有包含new操作的类(这里是ClasstToBeTested和FirstClass),PowerMock需要修改这些类的字节码来拦截构造函数。
  • PowerMockito.whenNew():这是核心方法,它会拦截指定类的构造调用,替换成我们的Mock对象。这样不管是FirstClass里的new SecondClass(),还是其他地方的调用,都会返回我们的Mock实例。
  • 为什么之前的@Spy没用?因为你Spy的FirstClass是测试类里创建的,而ClasstToBeTested内部是自己new了一个全新的FirstClass实例,两者毫无关联,自然Mock不会生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:42:27