CDI单元测试失败,限定符类型出现不符合要求的依赖项异常



Hi我定义了以下限定符类型。。

@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.joss.weld.exceptions.DeploymentException:weld-001408:具有限定符@SortAndFilterType的类型SortAndFilter Provider的依赖项不满足在注入点[BackedAnnotatedField]@Inject@SortAndFilterType private com.collabnet.ctf.saturn.client.apps.users.ChangeUsersStatus.mSortAndFilterProvider

我从这样的单元测试中调用它。。它与@RunWith(CdiRunner.class)一起运行

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

这里出了什么问题?

CDI的一个好处(这对您来说是一个问题)是它的类型安全解析将参数化类型中的参数考虑在内。换句话说:"CDI中没有类型擦除"规范对参数化类型解析非常详细:

参数化的bean类型被认为是可分配给参数化的所需类型,如果它们具有相同的原始类型,并且对于每个参数:

  • 所需的类型参数和bean类型参数是具有相同原始类型的实际类型,如果该类型是参数化的bean类型参数可分配给所需的类型参数根据这些规则,或者

  • 所需的类型参数是通配符,bean类型参数是实际类型,实际类型可分配给通配符的边界(如果有的话),并且可以从下界赋值,如果任意,通配符或

  • 所需的类型参数是通配符,bean类型参数是类型变量,类型变量的上限为可分配给或可从通配符,并且可以从通配符的下界(如果有的话)分配,或

  • 所需的类型参数是实际类型,bean类型参数是类型变量,实际类型可分配给变量或类型的上限(如果有的话)

  • required类型参数和bean类型参数都是类型变量,required类型形参的上限为可分配给bean类型参数的上限(如果有的话)。

您可以在此处阅读原文:http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#assignable_parameters.

现在Weld1.x对这一点不够严格,并接受将参数化类型分配给其原始类型。这可能就是为什么您在运行时(例如使用JBoss AS 7.x运行)没有问题,并且在测试中也有这个问题(cdi runner可能使用的是Weld 2.x)。是的,我在这里猜测,我可能错了,这就是为什么在问题中给出您使用的框架版本总是一件好事。

无论如何,你应该通过将你的注入点更改为来解决你的问题

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

它遵守规范,将在Weld 1.x和2.x 下工作

顺便说一句,你可能不需要你的限定词,因为之间不会有任何歧义

@Inject
private SortAndFilterProvider<Field,User> mSortAndFilterProvider1;

@Inject
private SortAndFilterProvider<Field,ReportList> mSortAndFilterProvider2;

嗨,这正是问题所在。我的运行时使用Jboss 7,测试环境使用CDI2.x

在将类型参数添加到注入点之后,它工作得非常好。

非常感谢。

最新更新