【问题标题】:CDI Unit Test fails with unsatisified dependency Exception for Qualifier TypeCDI 单元测试因限定符类型的依赖项异常而失败
【发布时间】:2014-11-10 23:14:42
【问题描述】:

您好,我定义了以下限定符类型..

@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: 带有限定符 @SortAndFilterType 的类型 SortAndFilterProvider 的依赖关系不满足 在注入点 [BackedAnnotatedField] @Inject @SortAndFilterType private com.collabnet.ctf.saturn.client.apps.users.ChangeUsersStatus.mSortAndFilterProvider

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

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

这里出了什么问题?

【问题讨论】:

  • 你能分享更多的测试代码吗?

标签: unit-testing mockito cdi jboss-weld cdi-unit


【解决方案1】:

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

参数化的 bean 类型被认为可以分配给参数化的 如果它们具有相同的原始类型和每个参数,则需要类型:

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

  • 必填类型参数为通配符,bean类型参数为实际类型,实际类型可赋值给上层 绑定,如果有的话,通配符和可从下限分配,如果 任何通配符,或

  • 需要的类型参数是通配符,bean类型参数是类型变量,类型变量的上限是 可分配给或可从其上限(如果有)分配 通配符,可从通配符的下限(如果有)分配, 或

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

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

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

现在 Weld 1.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;

【讨论】:

  • 嗨,这正是问题所在。
  • @user1882613,别忘了验证我的答案。
【解决方案2】:

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

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

非常感谢。

【讨论】:

  • 所以也许你可以验证我的答案;)
猜你喜欢
  • 2014-04-09
  • 1970-01-01
  • 2012-09-11
  • 2013-07-06
  • 2015-12-07
  • 2021-09-08
  • 2015-02-27
  • 1970-01-01
  • 2018-06-21
相关资源
最近更新 更多