如何使用Mockito注解注入带有@Value注解的构造方法参数
解决方案
报错根因
你的判断是对的,Mockito的@InjectMocks只会自动注入测试类中被@Mock/@Spy修饰的对象类型参数,@Value对应的String、int等基础/普通类型不属于Mock/Spy范畴,Mockito无法自动识别填充。且你的MyClass没有无参构造器,因此触发实例化失败异常。
可选解决方案
方案1:纯单元测试推荐,手动实例化MyClass(无Spring上下文,执行速度最快)
直接放弃@InjectMocks注解,手动构造MyClass实例,三个@Value参数直接传入测试用的固定值即可,该方案无需依赖Spring测试框架,仅用Mockito即可完成纯单元测试,是单元测试场景下的最优选择:
@ExtendWith(MockitoExtension.class) class MyClassTest { @Mock private MyService myservice; private MyClass myClass; @BeforeEach void init() { // 自定义三个@Value对应的测试值 myClass = new MyClass("http", "localhost", 8080, myservice); } // 后续测试方法 }
方案2:保留@InjectMocks写法,给普通参数加@Spy注解
如果不想改动原有@InjectMocks的写法,可以给三个@Value对应的参数添加@Spy注解并指定默认值,Mockito会识别到这些Spy对象并注入到构造器中:
@ExtendWith(MockitoExtension.class) class MyClassTest { @Spy private String protocol = "http"; @Spy private String host = "localhost"; @Spy private int port = 8080; @Mock private MyService myservice; @InjectMocks private MyClass myClass; // 后续测试方法 }
方案3:需要Spring上下文的集成测试场景
如果你的测试需要加载Spring配置、依赖Spring容器能力,可以使用SpringBoot测试注解搭配@TestPropertySource注入配置值:
@SpringBootTest @TestPropertySource(properties = { "my.protocol=http", "my.host=localhost", "my.port=8080" }) class MyClassTest { @MockBean private MyService myservice; @Value("${my.protocol}") private String protocol; @Value("${my.host}") private String host; @Value("${my.port}") private int port; private MyClass myClass; @BeforeEach void init() { myClass = new MyClass(protocol, host, port, myservice); } // 后续测试方法 }
内容的提问来源于stack exchange,提问作者user8473984
相关产品推荐
相关产品推荐

