Quarkus测试中jqwik注解方法注入Bean为NULL的问题解决
解决Quarkus中jqwik测试无法获取CDI注入Bean的问题
问题核心
在大型Quarkus项目中,使用jqwik的@Property、@Example、@Provider注解的方法无法访问CDI注入的Bean(示例中TreeRepository为null),但JUnit Jupiter的@Test方法可以正常获取。这是因为jqwik默认的测试实例创建逻辑与Quarkus的CDI注入生命周期不兼容,导致jqwik创建的测试实例没有经过Quarkus的注入处理。
解决方案
1. 实现自定义测试实例提供者
创建一个TestInstanceProvider实现类,让jqwik通过Quarkus的CDI容器获取测试实例,从而保证注入生效:
import net.jqwik.api.lifecycle.TestInstanceProvider; import javax.enterprise.inject.spi.CDI; public class QuarkusJqwikTestInstanceProvider implements TestInstanceProvider { @Override public <T> T provideInstance(Class<T> testClass) { return CDI.current().select(testClass).get(); } }
2. 绑定实例提供者到测试类
在测试类上添加@AddLifecycleHook注解,指定使用上面的自定义提供者,同时保留@QuarkusTest以启动Quarkus测试容器:
@QuarkusTest @AddLifecycleHook(QuarkusJqwikTestInstanceProvider.class) class MyTestClass { @Inject TreeRepository treeRepository; @Test void testSimple() { final Collection<Tree> trees = this.treeRepository.getTrees(); assertThat(trees).isNotEmpty(); } @Example void exampleSimple() { // 修正方法名重复问题 final Collection<Tree> trees = this.treeRepository.getTrees(); assertThat(trees).isNotEmpty(); } @Property void treesHaveLeaves(@Forall("tree") Tree tree) { assertThat(tree.getLeaves()).isNotEmpty(); } @Provider // 添加@Provider注解让jqwik识别数据源 Arbitrary<Tree> tree() { final Collection<Tree> trees = this.treeRepository.getTrees(); return Arbitraries.of(trees); } }
3. 全局生效配置(可选)
如果希望所有jqwik测试都自动使用该提供者,可以在src/test/resources/META-INF/services/net.jqwik.api.lifecycle.TestInstanceProvider文件中添加类的全限定名:
com.yourpackage.QuarkusJqwikTestInstanceProvider
4. 临时应急方案(不推荐)
如果来不及配置自定义提供者,可以在需要的方法中手动从CDI容器获取Bean:
TreeRepository treeRepository = CDI.current().select(TreeRepository.class).get();
依赖检查
确保pom.xml中包含正确的依赖版本:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>net.jqwik</groupId> <artifactId>jqwik-junit5</artifactId> <scope>test</scope> <!-- 建议使用最新稳定版 --> </dependency>
内容的提问来源于stack exchange,提问作者aaberg
相关产品推荐
相关产品推荐

