使用@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
相关产品推荐
相关产品推荐

