Arquillian测试中依赖注入失效问题求助
嘿,我在做JavaEE Arquillian测试的时候,也踩过好几次@Inject失效的坑,结合你给出的代码片段,大概率是这几个关键点没处理好,咱们一个个来排查修复:
1. 你的BookRepository还不是CDI可管理的Bean
你现在只给Repo加了@Transactional(SUPPORTS)注解,但这个注解仅用于事务管理,不会让类被CDI容器识别为可注入的Bean。在JavaEE规范中,要让一个类能通过@Inject注入,必须给它加上CDI的标识注解——要么是作用域注解(比如@ApplicationScoped、@RequestScoped),要么是@Named注解。
给你的BookRepository补上合适的注解,比如无状态的数据库访问类用@ApplicationScoped就很合适:
package com.pluralsight.bookstore.repository; import javax.enterprise.context.ApplicationScoped; import javax.transaction.Transactional; import static javax.transaction.Transactional.TxType.SUPPORTS; @ApplicationScoped @Transactional(SUPPORTS) public class BookRepository { // 你的仓库方法逻辑 }
2. Arquillian测试缺少核心的部署配置
从你贴的测试类代码来看,应该是没写@Deployment方法——这可是Arquillian测试的核心!你得明确告诉Arquillian,要把哪些类、资源打包部署到测试容器里。如果没有这个配置,或者部署包没包含BookRepository、缺少CDI必需的beans.xml,注入肯定会失败。
给你的测试类补上完整的部署配置:
package com.pluralsight.bookstore.repository; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Test; import org.junit.runner.RunWith; import javax.inject.Inject; @RunWith(Arquillian.class) public class BookRepositoryTest { @Inject private BookRepository bookRepository; // 必须的部署配置方法 @Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClasses(BookRepository.class) // 把你的仓库类加入部署包 .addAsManifestResource("META-INF/beans.xml", "beans.xml"); // 添加CDI激活文件(哪怕是空的) } // 先写个简单测试验证注入是否成功 @Test public void testRepositoryInjection() { assert bookRepository != null : "BookRepository注入失败!"; } }
这里要注意beans.xml文件:在JavaEE 7及以上版本中,这个文件可以是空的,但必须存在(放在src/main/resources/META-INF目录下),它的作用是告诉CDI容器启用Bean自动发现机制。
3. 检查测试容器的兼容性
确保你使用的Arquillian容器适配器是支持JavaEE完整特性的(比如WildFly、Payara的官方适配器),而不是轻量级的SE容器(比如Weld SE,虽然也能用,但需要额外配置事务支持)。如果用的是嵌入式容器,也要确认它包含了CDI和JTA(事务)的实现。
4. 基础细节检查
- 确认你导入的
@Inject是**javax.inject.Inject**(JavaEE标准注解),而不是其他框架的(比如Spring的org.springframework.beans.factory.annotation.Inject); - 检查
BookRepository的包名和测试类中导入的包名是否完全一致,有没有拼写错误;
如果做完以上步骤还是不行,建议查看Arquillian的测试日志,里面通常会有CDI Bean发现失败、部署异常等详细信息,能帮你定位具体问题。
内容的提问来源于stack exchange,提问作者Animu

