【问题标题】:CdiUnit test with Junit @Rule is impossible because of a public private field paradox由于公共私有领域悖论,无法使用 Junit @Rule 进行 CdiUnit 测试
【发布时间】:2017-03-03 17:27:03
【问题描述】:

下面的sn-p足以重现我的问题:

  • 要么我设置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

我删除了所有不必要的代码,但这是一个相当复杂的单元测试,其中包含模拟、通过 CDI 进行的服务注入以及一些预期会引发异常的测试方法。

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 希望 Rule 字段公开,因为它使用反射访问它们并且由于安全管理器处于活动状态而不想使用setAccessible(true) 方法。如何处理这个悖论?

注意:我还发现了 this answer 的提示 cmets,说明

你也可以用@Rule注解一个方法,这样可以避免这个问题

但我找不到任何在方法上带有@Rule 注释的junit 测试示例,我打算就此提出一个单独的问题。

【问题讨论】:

    标签: java junit cdi junit-rule cdi-unit


    【解决方案1】:

    我找到了解决问题的方法。为了将来参考,这里有一个可以工作的sn-p,希望这对其他人有帮助。

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

    【讨论】:

    • 非常好。我建议与 CdiUnit 团队一起进行增强,他们不一定要进行测试 @ApplicationScoped
    • 好主意,但只能部分发挥作用。您不能使用规则为使用 @Produces 的测试提供内容,因为在应用规则之前会调用 CDI 生产者。 :(
    猜你喜欢
    • 2018-05-10
    • 2017-04-09
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    相关资源
    最近更新 更多