QuarkusTest中@InjectMock/@InjectSpy注入报Bean无法解析错误怎么办
报错核心原因
- 认知误区:Quarkus中
@InjectMock/@InjectSpy的本质是容器已注册Bean的替换逻辑,不是自动生成Bean的逻辑。容器启动阶段会先完成全量CDI Bean的依赖校验,只要存在无法被容器识别解析的依赖,就会直接抛出could not resolve the bean of type错误,根本不会走到Mock替换的流程。 - 结合给出的
MyAppBean代码,常见触发场景有三类:- 注入的
Logger没有对应的CDI生产者,容器本身找不到Logger类型的合法Bean; - 注入的
GroupMapper没有配置为CDI托管Bean(比如MapStruct生成的Mapper未指定componentModel = "cdi"、MyBatis Mapper未被Quarkus扩展扫描注册); - 待Mock的Bean所在路径未被Quarkus扫描规则覆盖,容器根本没有注册对应类型的Bean。
- 注入的
- 额外触发场景:Quarkus版本过低(1.x早期版本)、
quarkus-junit5-mockito扩展版本与Quarkus核心版本不匹配,也会导致Mock注入逻辑失效抛出该错误。
解决方法
- 第一步:补全所有依赖的CDI Bean注册
确保所有被@Inject标注的依赖都能被Arc容器识别:- 针对Logger这类通用组件,编写CDI生产者类完成注册,参考代码:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; public class LoggerProducer { @Produces public Logger buildLogger(InjectionPoint point) { return LoggerFactory.getLogger(point.getMember().getDeclaringClass()); } } - 针对MapStruct的
GroupMapper,在@Mapper注解中指定组件模型为CDI:@Mapper(componentModel = "cdi");如果是MyBatis的Mapper,确认引入了quarkus-mybatis扩展且接口加了@Mapper注解,保证能被扫描注册为Bean。 - 注意:类中直接用
new关键字实例化的对象(比如示例中的ObjectMapper)不受容器管理,无法通过@InjectMock模拟,需要改成注入形式的托管Bean才能被Mock替换。
- 针对Logger这类通用组件,编写CDI生产者类完成注册,参考代码:
- 第二步:确认Bean扫描路径合规
所有自定义托管Bean必须放在项目启动类(标注@QuarkusMain的类)所在包的同级或子级目录下;如果是第三方包中的Bean,在测试类或启动类上用@Import(目标Bean.class)手动导入,保证容器能扫描到对应类型。 - 第三步:规范Mock注解的使用
@InjectMock/@InjectSpy要直接声明在测试类的公共字段上,字段类型和容器中注册的Bean类型保持一致,参考写法:import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.mockito.InjectMock; import javax.inject.Inject; @QuarkusTest public class MyAppBeanTest { @InjectMock GroupMapper groupMapper; @InjectMock Logger logger; @Inject MyAppBean testTarget; // 测试方法逻辑 } - 第四步:对齐依赖版本
升级到2.13.Final及以上的稳定版Quarkus,保证quarkus-junit5-mockito扩展版本和Quarkus核心版本完全一致,不要单独引入和Quarkus官方管理版本不一致的Mockito依赖。
内容的提问来源于stack exchange,提问作者Landister
相关产品推荐
相关产品推荐

