简体   繁体   English

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

[英]CdiUnit test with Junit @Rule is impossible because of a public private field paradox

The following snippet is enough to reproduce my problem: 以下代码段足以重现我的问题:

  • Either I set the thrown attribute public and get the error org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public field 我将thrown属性设置为public并获取错误org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public field
  • Or I remove the public modifier and get the error org.junit.internal.runners.rules.ValidationError: The @Rule 'thrown' must be public. 或者我删除public修饰符并获取错误org.junit.internal.runners.rules.ValidationError: The @Rule 'thrown' must be public.
  • I also tried to let the public modifier in place and to add the @Dependent annotation scope on the class, but got error org.jboss.weld.exceptions.DefinitionException: WELD-000046: At most one scope may be specified on [EnhancedAnnotatedTypeImpl] public @Dependent @ApplicationScoped @RunWith 我还试图让public修饰符到位并在类上添加@Dependent注释作用域,但是得到错误org.jboss.weld.exceptions.DefinitionException: WELD-000046: At most one scope may be specified on [EnhancedAnnotatedTypeImpl] public @Dependent @ApplicationScoped @RunWith

I stripped out all unnecessary code, but this is quite a complex unit test with mock, service injection through CDI and some test methods thar are expected to throw an exception. 我删除了所有不必要的代码,但这是一个非常复杂的单元测试,通过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() {

    }
}

So my problem is that on one hand Weld wants all fields to not be public because it will not be able to proxify the class otherwise, and on the other hand, JUnit want Rule fields to be public because it is using reflection to access them and does not want to use the setAccessible(true) method because of the cases where the security manager is active. 所以我的问题是,一方面Weld希望所有字段都不公开,因为否则它将无法代理该类,另一方面,JUnit希望规则字段是公共的,因为它使用反射来访问它们由于安全管理器处于活动状态,因此不希望使用setAccessible(true)方法。 How to deal with that paradox? 如何处理这个悖论?

NB: I also found a hint comments to this answer , stating that 注意:我也发现了对这个答案的暗示评论,并说明了这一点

You can also annotate a method with @Rule, so this would avoid the problem 您还可以使用@Rule注释方法,这样可以避免此问题

But I could not found any example of junit test with a @Rule annotation on a method, I plan to ask a separate question about this. 但我找不到任何关于方法的@Rule注释的junit测试的例子,我打算问一个单独的问题。

I found out how to solve the problem. 我发现了如何解决这个问题。 For future reference, here is a snippet that works, hope this will help other people. 为了将来参考,这是一个有用的片段,希望这将有助于其他人。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM