所以我认为这很简单,但后来:
我有一些小测试。它测试 CDI 依赖注入(inject):
//Imports
@RunWith(Arquillian.class)
public class EditCustomerTest
{
@Deployment
public WebArchive createTestArchive()
{
return ShrinkWrap
.create(WebArchive.class, "testcrm.war")
.addClass(CustomerListProducer.class)
.addPackage("company.product.controller")
.addPackage("company.product.model")
.addPackage("company.product.util")
.addPackage("company.product.services")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsResource("test-ds.xml", "ds.xml")
.addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml");
}
@Inject
CustomerEditController customerEditController;
@Inject
List<Customer> customers;
@Test
public void testInjectionResolution(){
Assert.assertNotNull(customerEditController);
//do some stuff, where actually nothing happens
}
}
CustomerEditController 注入(inject)一个私有(private)的 CustomerListController,后者本身注入(inject)一个私有(private)的 CustomerDetailsController。
所有 Controller 都是 SessionScoped(我知道我不应该这样做,但无论哪种方式,它都是一个原型(prototype)项目,而且我还无法让事件运行。)
Resources 是一个自定义类,用于提供 Logger、用于持久化的 EntityManager 和用于错误消息的 FacesContext。
所有 Controller 都在“company.product.controller”包中
当我现在将此测试作为标准 JUnit 测试运行时 (Alt
+ Shift
+ X
, T
) 我收到错误消息:
org.jboss.arquillian.container.spi.client.container.DeploymentException: Could not deploy to container: {"JBAS014671: Failed services" => {"jboss.deployment.unit.\"testCDI.war\".WeldService" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"testCDI.war\".WeldService: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [CustomerDetailsController] with qualifiers [@Default] at injection point [[field] @Inject company.product.controller.CustomerListController.customerDetailsController]"}}
我试图在 addClasses 调用中显式添加所有 Controller ,但遗憾的是结果没有任何变化。
编辑:
这是一个骨架化的 CustomerListProducer:
@ApplicationScoped
public class CustomerListProducer implements Serializable{
@Inject
CustomerService customerServiceBean;
private static final long serialVersionUID = 1L;
private List<Customer> customers = new ArrayList<Customer>();
private Random rnd;
//some private static final String[] to create DummyData from
@PostConstruct
public void init(){
//check if database is empty, and if then generate DummyData and persist them
}
//these call the ServiceBeans implementation to persist the changes
//the qualifiers are declared in class Events in the package company.product.util
public void onCustomerAdded(@Observes @Added Customer customer);
public void onCustomerDeleted(@Observes @Deleted Customer customer);
public void onCustomerUpdated(@Observes @Updated Customer customer);
@Named
@Produces
public List<Customer> getCustomers();
}
所有 Controller 的工作方式几乎相同,注释 相同,因此我将在此处发布其中一个:
@Named
@SessionScoped
public class CustomerDetailsController implements Serializable {
private static final long serialVersionUID = 1L;
private Customer customer = new Customer();
// Inject dependent Controllers. there are no events to pass data between views yet
@Inject
ContractEditController contractEditController;
@Inject
AddContactPersonController addContactPersonController;
@Inject
Resources res;
@Named
@Produces
public Customer getCustomer();
//CRUD-Events for the Customer that are fired, to persist modifications
}
这里是服务:
@Named
@ApplicationScoped
public interface CustomerService{
public List<Customer> getAllCustomers();
public void addCustomer(Customer c);
public void deleteCustomer(Customer c);
public void updateCustomer(Customer c);
}
这是相应的实现:
@Stateless
public class CustomerServiceBean implements CustomerService{
@Inject
EntityManager entityManager;
//implementations for the CustomerService Methods, using the Entity Manager
}
编辑 2:
在评论了有问题的注入(inject) CustomerDetailsController(即使我真的需要它)之后,我收到了一条新的错误消息:Could not inject CDI Bean
在 StackTrace 中移动了一下,我发现不包括持久性,所以我调整了 @Deployment 方法。不幸的是,现在我得到了错误,我的持久性单元找不到数据源。
我仔细检查了这些名称,我确定它们是相同的。
最佳答案
经过几个小时的搜索,我发现(如问题中所述)CustomerListProducer 和服务包中使用的 hibernate 数据源配置不正确。
感谢@rubenlop88,我能够以正确的方式添加数据源。这解决了潜在的冲突。我仍然从缺少的服务包中得到一大堆错误。
为了更轻松地创建新测试并集中创建测试存档,我引入了一个新的抽象类,它为所有测试执行此操作:
@RunWith(Arquillian.class)
public abstract class TestBundle{
@Deployment
public static WebArchive createTestArchive() {
return ShrinkWrap
.create(WebArchive.class, "testArchive.war")
.addClass(CustomerListProducer.class)
.addPackage("company.product.controller")
.addPackage("company.product.model")
.addPackage("company.product.util")
.addPackage("company.product.services")
.addPackage("company.product.test")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource("test-ds.xml", "product-ds.xml")
.addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml");
}
}
这个类被所有测试扩展,所以任何对包生成必要的更改都可以集中进行
关于java - 对显式添加的类的 CDI 依赖注入(inject)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20330687/