由于公共私人领域的矛盾,使用Junit @Rule的CdiUnit测试是不可能的

以下代码段足以重现我的问题:

  • 我将thrown属性设置为public并获取错误org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public field
  • 或者我删除public修饰符并获取错误org.junit.internal.runners.rules.ValidationError: The @Rule 'thrown' must be public.
  • 我还试图让public修饰符到位,并在类上添加@Dependent注释范围,但得到错误org.jboss.weld.exceptions.DefinitionException: WELD-000046: At most one scope may be specified on [EnhancedAnnotatedTypeImpl] public @Dependent @ApplicationScoped @RunWith

我删除了所有不必要的代码,但这是一个非常复杂的unit testing,通过CDI进行模拟,服务注入,并且一些测试方法预计会引发exception。

 import org.jglue.cdiunit.CdiRunner; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; @RunWith(CdiRunner.class) public class FooBarTest { @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void test() { } } 

所以我的问题是,一方面Weld希望所有字段都不公开,因为否则它将无法代理该类,另一方面,JUnit希望规则字段是公共的,因为它使用reflection来访问它们由于安全管理器处于活动状态,因此不希望使用setAccessible(true)方法。 如何处理这个悖论?

注意:我也发现了对这个答案的暗示评论,并说明了这一点

您还可以使用@Rule注释方法,这样可以避免此问题

但我找不到任何关于方法的@Rule注释的junit测试的例子,我打算问一个单独的问题。

我发现了如何解决这个问题。 为了将来参考,这是一个有效的片段,希望这将有助于其他人。

 import org.jglue.cdiunit.CdiRunner; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; @RunWith(CdiRunner.class) public class FooBarTest { private ExpectedException thrown = ExpectedException.none(); @Rule public ExpectedException getThrown() { return thrown; } @Test public void test() { thrown.expect(ArithmeticException.class); int i = 1 / 0; } }