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

QuarkusTest如何在JUnit5扩展中访问测试上下文Bean

Quarkus测试中通过JUnit 5扩展编程式获取CDI Bean的实现方案

你遇到的java.lang.IllegalStateException: Unable to locate CDIProvider异常,本质是原生JUnit 5扩展的回调执行时机早于Quarkus测试CDI容器的初始化节点,此时CDI上下文还没绑定到当前线程,直接调用CDI.current()自然无法找到容器实例。
Quarkus测试框架提供了和Spring SpringExtension.getApplicationContext()完全对等的能力,不需要在测试类中通过@Inject注入Bean,可以直接封装成可复用的通用扩展。

核心API说明

Quarkus的JUnit 5集成模块提供了io.quarkus.test.junit.QuarkusTestExtension工具类,你可以通过它的getBeanManager(ExtensionContext context)静态方法直接获取当前测试上下文关联的CDI BeanManager,拿到BeanManager后就可以正常查询、获取任意CDI Bean实例。

方法级回调实现(BeforeEach/AfterEach)

如果只需要在每个测试方法执行前后操作Bean,直接实现JUnit原生的BeforeEachCallback/AfterEachCallback接口即可,在回调方法中先通过上述API获取BeanManager,再操作CDI容器:

import io.quarkus.test.junit.QuarkusTestExtension;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.CDI;

public class ReusableTestExtension implements BeforeEachCallback, AfterEachCallback {

    @Override
    public void beforeEach(ExtensionContext extensionContext) {
        // 触发BeanManager加载,完成CDI上下文绑定
        BeanManager beanManager = QuarkusTestExtension.getBeanManager(extensionContext);
        // 直接获取目标Bean实例,和Spring context.getBean()逻辑一致
        MyBean targetBean = CDI.current().select(MyBean.class).get();
        // 编写自定义Bean交互逻辑
    }

    @Override
    public void afterEach(ExtensionContext extensionContext) {
        BeanManager beanManager = QuarkusTestExtension.getBeanManager(extensionContext);
        MyBean targetBean = CDI.current().select(MyBean.class).get();
        // 编写测试执行后的收尾逻辑
    }
}

类级回调实现(BeforeAll/AfterAll)

如果需要在测试类所有方法执行前的类级别节点操作Bean,不要直接使用JUnit原生的BeforeAllCallback/AfterAllCallback接口,这类回调的执行时机不受Quarkus控制,会出现容器未初始化的问题。你需要实现Quarkus自定义的对应回调接口,框架会保证回调触发时CDI容器已经完成启动:

import io.quarkus.test.junit.QuarkusTestExtension;
import org.junit.jupiter.api.extension.ExtensionContext;
import javax.enterprise.inject.spi.CDI;

public class ReusableTestExtension implements QuarkusTestExtension.BeforeAllCallback, QuarkusTestExtension.AfterAllCallback {

    @Override
    public void beforeAll(ExtensionContext context) {
        // 此处CDI容器已完成初始化,可直接获取Bean
        MyBean targetBean = CDI.current().select(MyBean.class).get();
        // 编写类级别的初始化逻辑
    }

    @Override
    public void afterAll(ExtensionContext context) {
        MyBean targetBean = CDI.current().select(MyBean.class).get();
        // 编写类级别的销毁逻辑
    }
}

注意事项

  • 上述扩展仅支持标注了@QuarkusTest的测试类使用,和Spring测试扩展仅能在Spring测试上下文使用的限制一致
  • 不要在扩展的构造方法、原生JUnit的非测试方法级回调中直接调用CDI.current(),这类节点执行时Quarkus容器可能未完成初始化
  • 如果需要对Bean做条件匹配(比如指定名称、指定限定符),既可以用CDI.current().select()的重载方法传入匹配规则,也可以直接通过拿到的BeanManager API做更灵活的实例查询

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:57:18