2016-10-21 25 views
2

下面的片段就足以重現我的問題:使用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.
  • 我也試圖讓到位,並添加類上的@Dependent註釋範圍public修改,但得到的錯誤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() { 

    } 
} 

所以我的問題是,一方面焊接希望,因爲它無法以其他方式proxify類的所有字段不公開,而另一方面,JUnit的希望規則字段是公共的,因爲它正在使用反射來訪問它們,並且由於安全管理器處於活動狀態,因此不想使用setAccessible(true)方法。如何處理這個悖論?

注:我也發現了一絲評論this answer,指出

您也可以標註與@rule的方法,因此這將避免該問題

但我無法找到在方法上使用@Rule註釋進行junit測試的任何示例,我打算就此問一個單獨的問題。

回答

9

我發現瞭如何解決這個問題。爲了將來的參考,這裏是一個有效的片段,希望這可以幫助其他人。

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

非常好。我會建議提高CdiUnit團隊的增強功能,他們不一定會進行測試'@ ApplicationScoped'。 –

+0

不錯的想法,但只能部分工作。您不能使用規則爲使用@Produces的測試提供事物,因爲在應用規則之前調用CDI生產者。 :( – Gandalf