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

使用@Spy和@InjectMocks模拟多个Vector<String>的JUnit测试问题

没问题,我来帮你搞定这个注入的问题。首先要注意的核心点是:你的两个依赖都是Vector<String>类型,直接用@Spy的话,Mockito没办法自动区分哪个该注入到firstVector,哪个对应secondVector,所以我们需要给这两个依赖加上限定符来标记,再配合@InjectMocks完成精准注入。

步骤1:给原代码的依赖添加限定符

首先修改你的AbstractMyObject,给两个@Autowired的Vector字段加上@Qualifier注解,指定唯一名称,让后续测试能精准匹配:

@AllArgsConstructor
public abstract class AbstractMyObject {
    @Autowired
    @Qualifier("firstVector") // 添加限定符标记第一个Vector
    private Vector<String> firstVector;
    @Autowired
    @Qualifier("secondVector") // 添加限定符标记第二个Vector
    private Vector<String> secondVector;
    
    public abstract void absFunc();
    public void doThis() {
        System.out.println(firstVector);
        System.out.println(secondVector);
    }
}

对应的,MyObject的构造函数参数也需要加上对应@Qualifier,确保注入逻辑能匹配上:

@Component
public class MyObject extends AbstractMyObject {
    public MyObject(
        @Qualifier("firstVector") final Vector<String> firstVector,
        @Qualifier("secondVector") final Vector<String> secondVector
    ) {
        super(firstVector, secondVector);
    }
}

步骤2:编写JUnit测试类

接下来编写测试类,用@Spy创建两个Vector的spy对象,并用@Qualifier标记对应名称,再通过@InjectMocks自动注入到MyObject中:

JUnit 5 版本(推荐)

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.Vector;

@ExtendWith(MockitoExtension.class)
public class MyObjectTest {

    // 创建第一个Vector的spy,绑定对应限定符
    @Spy
    @Qualifier("firstVector")
    private Vector<String> firstSpyVector = new Vector<>();
    
    // 创建第二个Vector的spy,绑定对应限定符
    @Spy
    @Qualifier("secondVector")
    private Vector<String> secondSpyVector = new Vector<>();
    
    // 自动注入MyObject,Mockito会根据限定符匹配对应的spy
    @InjectMocks
    private MyObject myObject;

    @Test
    public void testDoThis() {
        // 给spy添加自定义数据,模拟业务场景
        firstSpyVector.add("test-first-element");
        secondSpyVector.add("test-second-element");
        
        myObject.doThis();
        
        // 验证spy的方法是否被正确调用
        org.mockito.Mockito.verify(firstSpyVector).toString();
        org.mockito.Mockito.verify(secondSpyVector).toString();
    }
}

JUnit 4 版本

如果使用JUnit 4,只需要替换启动注解即可,其余代码完全一致:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.Vector;

@RunWith(MockitoJUnitRunner.class)
public class MyObjectTest {

    @Spy
    @Qualifier("firstVector")
    private Vector<String> firstSpyVector = new Vector<>();
    
    @Spy
    @Qualifier("secondVector")
    private Vector<String> secondSpyVector = new Vector<>();
    
    @InjectMocks
    private MyObject myObject;

    @Test
    public void testDoThis() {
        firstSpyVector.add("test-first-element");
        secondSpyVector.add("test-second-element");
        
        myObject.doThis();
        
        org.mockito.Mockito.verify(firstSpyVector).toString();
        org.mockito.Mockito.verify(secondSpyVector).toString();
    }
}

关键细节说明

  • @Spy创建的是真实对象的spy包装:你可以保留原Vector的所有原生行为,也可以针对性mock特定方法;如果需要完全模拟对象,也可以替换成@Mock,但按你的要求这里用@Spy实现。
  • @Qualifier是解决冲突的核心:因为两个依赖类型完全相同,Mockito的@InjectMocks默认按类型匹配会出现歧义,加上限定符后就能精准对应到目标字段/构造参数。
  • 若不想修改原代码,也可以用ReflectionTestUtils手动给MyObject的字段赋值,但这种方式不够优雅,还是给原代码添加限定符的方案更规范易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:18:06