Сбой модульного теста CDI с неудовлетворенной зависимостью Исключение для типа квалификатора

Привет, я определил следующий тип квалификатора..

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.FIELD })
public @interface SortAndFilterType {

/**
 * The value for the sort and filter.
 *
 * @return the sort and filter type value.
 */
String value();
}

И две реализации из этого.

@SortAndFilterType("Users")
public class UserSortAndFilterProviderImpl implements SortAndFilterProvider<Field, User>       {}

@SortAndFilterType("ReportsList")
public class ReportListSortAndFilterProviderImpl implements SortAndFilterProvider<Field, ReportList> {}

И я делаю инъекцию от Клиента как...

@Inject
@SortAndFilterType("Users")
private SortAndFilterProvider mSortAndFilterProvider;

Все работает хорошо во время выполнения..

Но проблема возникает, когда я запустил модульные тесты..

Я получаю следующее исключение..

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Неудовлетворенные зависимости для типа SortAndFilterProvider с квалификаторами @SortAndFilterType в точке внедрения [BackedAnnotatedField] @Inject @SortAndFilter.yatat. mSortAndFilterProvider

Я вызываю это из модульных тестов, как это.. он работает с @RunWith(CdiRunner.class)

@Produces
@SortAndFilterType("Users")
@Mock
private SortAndFilterProvider mSortAndFilterProvider;

Что здесь не так?

2 ответа

Одна хорошая вещь с CDI (которая является проблемой для вас здесь) состоит в том, что его безопасное разрешение типов учитывает параметр в параметризованных типах. Другими словами: "нет стирания типов в CDI" В спецификации очень подробно описано разрешение параметризованных типов:

Параметризованный тип компонента считается назначаемым параметризованному требуемому типу, если он имеет идентичный необработанный тип и для каждого параметра:

  • требуемый параметр типа и параметр типа компонента являются фактическими типами с идентичным необработанным типом, и, если тип параметризован, параметр типа компонента может быть назначен требуемому параметру типа в соответствии с этими правилами, или

  • обязательный параметр типа является подстановочным знаком, параметр типа bean-компонента является фактическим типом, и фактический тип присваивается верхней границе, если есть, подстановочного знака и назначается из нижней границы, если есть, подстановочного знака, или

  • обязательный параметр типа - это подстановочный знак, параметр типа bean-компонента - это переменная типа, а верхняя граница переменной типа может быть назначена или назначена из верхней границы, если есть, подстановочного знака и назначена из нижней границы, если есть, подстановочного знака, или

  • обязательный параметр типа является фактическим типом, параметр типа bean-компонента является переменной типа, а фактический тип назначается верхней границе, если таковая имеется, переменной типа, или

  • требуемый параметр типа и параметр типа компонента являются переменными типа, и верхняя граница требуемого параметра типа может быть назначена верхней границе, если таковая имеется, параметра типа компонента.

Вы можете прочитать оригинальный текст здесь: http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html.

Теперь Weld 1.x недостаточно строг в этом вопросе и допускает присвоение параметризованного типа его необработанному типу. Вероятно, поэтому у вас нет проблем во время выполнения (например, с JBoss AS 7.x), и у вас есть эта проблема в вашем тесте (cdi-runner, вероятно, использует Weld 2.x). Да, я предполагаю здесь, и я могу ошибаться, поэтому всегда полезно дать версию фреймворка, которую вы используете в своем вопросе.

В любом случае вы должны решить свою проблему, изменив точку инъекции на

@Inject
@SortAndFilterType("Users")
private SortAndFilterProvider<Field,?> mSortAndFilterProvider; 

Он соответствует спецификации и будет работать под сваркой 1.x и 2.x.

Кстати, вам, вероятно, не нужен ваш классификатор, так как не будет никакой двусмысленности между:

@Inject
private SortAndFilterProvider<Field,User> mSortAndFilterProvider1;

а также

@Inject
private SortAndFilterProvider<Field,ReportList> mSortAndFilterProvider2;

Привет, это именно проблема. и моя среда выполнения использует Jboss 7, а среда тестирования использует CDI 2.x.

После добавления параметров типа в точку инъекции он работает отлично.

Большое спасибо.

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