Quarkus升级后@InjectMock对@ApplicationScoped的RestClient失效如何解决
问题原因
- Quarkus 2.x 调整了 REST Client 的默认作用域:1.x 版本中
@RegisterRestClient标注的接口默认作用域是@ApplicationScoped(标准 CDI 正常作用域),2.x 版本默认改为了@Singleton(CDI 伪作用域)。而@InjectMock默认仅支持注入标准 CDI 正常作用域的 Bean,伪作用域会触发本次报错。 - 你在接口上加的
@ApplicationScoped注解未生效:一方面@RegisterRestClient自带的scope属性优先级高于接口上直接添加的作用域注解;另一方面你导入的@ApplicationScoped是javax包下的,但引入的 CDI 依赖是jakarta命名空间的,两者不匹配,注解不会被 CDI 容器识别。
解决方案
以下方案按落地成本从低到高排序,任选其一即可:
方案一:开启
@InjectMock作用域转换能力
直接修改测试类的@InjectMock注解,添加convertScopes = true参数,无需修改业务代码:@QuarkusTest class MyTest { @InjectMock(convertScopes = true) @RestClient CloudEventPublisher cloudEventPublisherMock; @Test void mytest() { // 原有测试逻辑不变 } }该参数会让
@InjectMock兼容伪作用域的 Bean 注入,最适合测试场景快速修复问题。方案二:显式指定 REST Client 作用域
首先删除 pom.xml 中额外引入的jakarta.enterprise:jakarta.enterprise.cdi-api依赖(Quarkus 2.x 全栈使用javax命名空间,quarkus-arc依赖已经自带了正确版本的 CDI API,额外引入会导致包冲突),然后修改CloudEventPublisher接口的注解:import javax.enterprise.context.ApplicationScoped; import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; // 其余导包保持不变 @Path("/") @RegisterRestClient(scope = ApplicationScoped.class) // 直接在注解里指定作用域,不需要单独加@ApplicationScoped @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public interface CloudEventPublisher { @POST void publishOrder(CloudEvent cloudEvent); }该方案从根源调整 REST Client 作用域,适合需要在生产环境也使用
@ApplicationScoped的场景。
内容的提问来源于stack exchange,提问作者MGubler
相关产品推荐
相关产品推荐

