Сбой модульного теста 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.
После добавления параметров типа в точку инъекции он работает отлично.
Большое спасибо.