Альтернативная реализация CDI - WELD-001408: Неудовлетворенные зависимости для репозитория типов с квалификаторами @Default - PullRequest
0 голосов
/ 07 октября 2018

У меня есть интерфейс Repository с двумя реализациями, DBRepository и UTRepository.UTRepository помечено @Alternative, и я пытаюсь использовать его в тесте JUnit.

Класс теста:

@RunWith(Arquillian.class)
public class UserServiceTest {
    @Inject
    private UserService service;

    @Deployment
    public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class)
            .addClasses(Repository.class, UserService.class, UTRepository.class)
            .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Test
    public void addCharacterTest() {
        service.addCharacter(1L, Mockito.mock(GameCharacter.class));
    }
}

Тестируемый класс:

public class UserService {
    @Inject
    Repository repository;

    @Transactional
    public void addCharacter(Long userId, GameCharacter character) {
        User user = repository.readById(userId, User.class);
        user.addCharacter(character);
        repository.update(user);
    }
}

Мой beans.xml файл (помещен в src / test / webapp / WEB-INF / beans.xml):

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/beans_1_2.xsd"
    bean-discovery-mode="all">
    <alternatives>
        <class>org.package.name.UTRepository</class>
    </alternatives>
</beans>

Когда я пытаюсь запустить тест, я получаю исключение:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type Repository with qualifiers @Default
    at injection point [BackedAnnotatedField] @Inject org.package.name.services.UserService.repository
    at org.package.name.services.UserService.repository(UserService.java:0)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:63)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:56)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

В чем проблема?

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Решение, которое вы нашли, работает хорошо, так что просто для полноты.

В основном вам нужно добавить beans.xml, что позволит вам выбрать альтернативу.EmptyAsset.INSTANCE приведет к пустому бобу beans.xml, который в этом случае его не обрежет.

Однако в вашем решении beans.xml, который вы поместили в src/test/webapp/WEB-INF/beans.xml, ничего не делает. Если вы хотите использовать существующий beans.xml файл , вы можете использовать:

  • addAsManifestResource(File resource, String target), который добавляет File как имя target
  • addAsManifestResource(Package resourcePackage, String resourceName, String target), который позволяет вам указать только пакет, в котором находится файл, затем его имя и имя файла, под которым вы хотите его в своем развертывании
0 голосов
/ 07 октября 2018

Кажется, проблема в .addAsManifestResource аргументах.Я должен использовать StringAsset с альтернативами, которые Arquillian добавит в beans.xml, а не пустой экземпляр.

Теперь это метод createDeployment():

@Deployment
public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class)
        .addClasses(Repository.class, UserService.class, UTRepository.class)
        .addAsManifestResource(new StringAsset("<alternatives><class>org.package.name.repositories.UTRepository</class></alternatives>"), "beans.xml");
}
...