Инъекция зависимостей CDI в явно добавленные классы завершается неудачно

Так я думал, что это будет просто, но тогда:

У меня есть небольшой тест. Тестирует инъекцию зависимости CDI:

//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 внедряет частный CustomerListController, который сам вводит частный CustomerDetailsController.
Все контроллеры являются SessionScoped (я знаю, что не должен, но в любом случае это прототип, также я не смог запустить события).
Ресурсы - это пользовательский класс, предоставляющий Logger, EntityManager для постоянства и FacesContext для сообщений об ошибках. Все контроллеры находятся в пакете "company.product.controller"

Когда я сейчас запускаю этот тест как стандартный тест JUnit (Alt + Shift + X, T) я получаю сообщение об ошибке:

org.jboss.arquillian.container.spi.client.container.DeploymentException: Не удалось развернуть в контейнере: {"JBAS014671: Сбой служб" => {"jboss.deployment.unit.\"testCDI.war\".WeldService" => "org.jboss.msc.service.StartException в службе jboss.deployment.unit. \" testCDI.war \ ". WeldService: org.jboss.weld.exceptions.DeploymentException: WELD-001408 Неудовлетворенные зависимости для типа [CustomerDetailsController] квалификаторы [@Default] в точке внедрения [[field] @Inject company.product.controller.CustomerListController.customerDetailsController]"}}

Я попытался добавить все контроллеры явно в вызове addClasses, но, к сожалению, в результате не было никаких изменений.

РЕДАКТИРОВАТЬ:

Вот скелетный 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();
}

Все контроллеры работают практически одинаково, аннотации одинаковы, поэтому я просто опубликую один из них здесь:

@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:
После комментирования проблемного введенного CustomerDetailsController (даже если он мне действительно нужен) я получил новое сообщение об ошибке: Could not inject CDI Bean
Пройдя немного по StackTrace, я обнаружил, что постоянство не включено, поэтому я настроил метод @Deployment. к сожалению, теперь я получаю сообщение об ошибке, что мой блок постоянства не может найти источник данных.

Я дважды проверил имена, и я уверен, что они одинаковы.

2 ответа

Решение

После нескольких часов поиска я обнаружил, что (как упоминалось в вопросе) источник данных гибернации, используемый в CustomerListProducer и пакете услуг, был настроен неправильно.

Благодаря @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");
     }
}

этот класс расширяется всеми тестами, поэтому любые изменения, необходимые для генерации пакетов, можно сделать централизованными

Чтобы указать на очевидное, CustomerDetailsController имеет аннотацию квалификатора (@Named), которая предотвращает его использование при внедрении по умолчанию. Вот о чем предупреждает сварка. Вам нужно будет либо удалить классификатор из компонента, либо добавить его к точке инъекции.

Другие вопросы по тегам