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

如何在JUnit中Mock类内部依赖并捕获Void方法的调用参数

问题出得很典型——你测试里mock的ClassB对象,和A的method1内部自己new出来的ClassB完全是两个毫无关系的实例!Mockito根本监控不到后者的调用,自然会报mock未被调用的错误。

要解决这个问题,核心是让A使用你创建的mock实例,而不是自己去new。最合理的方式是通过依赖注入重构原代码,然后在测试中把mock对象注入进去。下面是具体的修改步骤:

1. 重构原类A,支持依赖注入

把ClassB的实例通过构造函数传入A,而不是在方法内部new:

class A{
    private final ClassB b;

    // 构造注入ClassB依赖
    public A(ClassB b) {
        this.b = b;
    }

    public void method1(String name){
        // 不再创建新的ClassB实例,使用注入的对象
        // 这里的argument1是你业务逻辑里的参数,保持不变
        b.method2(argument1);
    }
}

(注意:Java类名规范是首字母大写,建议把classB改成ClassB,避免混淆)

2. 修改测试类,让Mock生效

在测试中,我们用Mockito的@Mock创建ClassB的mock实例,再通过@InjectMocks自动注入到A的实例中,同时别忘了给测试方法加@Test注解:

import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;

class ATest{
    private String name = "name";

    @Mock
    private ClassB mockB;

    @InjectMocks
    private A a;

    @Before
    public void setup(){
        // 初始化Mockito的注解
        MockitoAnnotations.openMocks(this);
        // 如果你不想用@InjectMocks,也可以手动创建A实例:
        // a = new A(mockB);
    }

    @Test
    public void testMethod1() {
        // 调用被测方法
        a.method1(name);

        // 创建参数捕获器
        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

        // 验证mockB的method2被调用1次,并捕获传入的参数
        verify(mockB, times(1)).method2(captor.capture());

        // 获取捕获的参数并做断言
        String actual = captor.getValue();
        assertEquals("some data", actual);
    }
}

额外注意事项

  • 测试方法必须标注@Test注解,否则JUnit不会执行这个测试用例
  • 如果因为某些原因不能修改原类的构造函数,也可以用PowerMockito来mocknew ClassB()这个动作,但这种方式属于侵入式测试,不推荐,最好还是通过依赖注入解耦代码,让测试更优雅。

内容的提问来源于stack exchange,提问作者Chandan Kumar Barik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:42:09