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

如何用Mockito Spy验证Class1中Class2实例创建及方法调用

解决方案

因为原代码中Class1直接在myMethod内部实例化Class2,Mockito默认无法拦截构造函数调用(且你无法修改POM引入PowerMock这类工具),所以我们可以通过微调Class1的代码,将Class2的创建逻辑抽成可覆盖的方法,再结合Mockito Spy来实现验证需求。

步骤1:调整Class1代码

把创建Class2的逻辑提取为一个非私有方法(比如protected权限),这样Spy对象可以覆盖这个方法:

public class Class1 {
    public Class1(){}

    public void myMethod(List<String> list){
        for (String element: list){
            Class2 class2 = createClass2(element); // 替换直接new的逻辑
            class2.anotherMethod();
        }
    }

    // 提取出来的创建方法,供Spy拦截
    protected Class2 createClass2(String element) {
        return new Class2(element);
    }
}

步骤2:编写测试用例

通过SpyClass1,拦截createClass2方法返回Mock的Class2实例,以此验证每个列表元素对应一次实例创建,且anotherMethod被执行:

import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Class1Test {

    @Test
    public void myMethod_CreatesClass2ForEachElementAndCallsAnotherMethod() {
        // 测试数据:3个元素的列表
        List<String> testElements = Arrays.asList("foo", "bar", "baz");
        List<Class2> class2Mocks = new ArrayList<>();

        // 创建Class1的Spy对象
        Class1 class1Spy = Mockito.spy(new Class1());

        // 拦截createClass2方法,每次调用返回一个Mock的Class2并收集起来
        Mockito.doAnswer(invocation -> {
            Class2 mockClass2 = Mockito.mock(Class2.class);
            class2Mocks.add(mockClass2);
            return mockClass2;
        }).when(class1Spy).createClass2(Mockito.anyString());

        // 执行待测试方法
        class1Spy.myMethod(testElements);

        // 验证1:createClass2被调用的次数等于列表元素数量
        Mockito.verify(class1Spy, Mockito.times(testElements.size()))
                .createClass2(Mockito.anyString());

        // 验证2:每个Mock的Class2实例都调用了anotherMethod
        for (Class2 mock : class2Mocks) {
            Mockito.verify(mock).anotherMethod();
        }

        // 可选:验证每个createClass2调用的参数和列表元素一致
        Mockito.verify(class1Spy).createClass2("foo");
        Mockito.verify(class1Spy).createClass2("bar");
        Mockito.verify(class1Spy).createClass2("baz");
    }
}

原理说明

  • 提取createClass2方法后,我们可以通过Spy对象覆盖这个方法的行为,替换为返回Mock实例,避免真正创建Class2对象。
  • 收集所有Mock的Class2实例后,就能直接验证每个实例的anotherMethod是否被调用。
  • 同时通过verify方法确认createClass2的调用次数和参数,确保每个列表元素都对应一次Class2的创建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:57:23