CDI单元测试失败,依赖性不合格,限定符类型的异常

时间:2014-09-17 03:22:06

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

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

@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;

这里出了什么问题?

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

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

将类型参数添加到注入点后,它可以正常工作。

非常感谢。