2017-01-27 65 views
0

我們正在將我們的JavaEE應用程序從Weblogic 10.3.6遷移到Weblogic 12.2.1.2。作爲此遷移的一部分,我們正在將我們的JSF管理bean更改爲使用CDI註釋而非標準JSF註釋。 @ManagedBean@Namedjavax.faces.bean.ViewScopedjavax.faces.view.ViewScoped。事實證明,這只是小問題而已。但是,我有一個很大的問題試圖讓我們的測試運行。測試失敗,出現以下錯誤:Arquillian測試JSF與CDI - CDI範圍問題

WebBeans context with scope type annotation @ViewScoped does not exist within current thread 

我嘗試了多個不同的容器(嵌入式和遠程),但仍然得到這個相同的錯誤。任何幫助將非常感激。

我使用的Arquillian具有以下pom.xml的依賴關係:

<dependencyManagement> 
    <dependencies> 
     <dependency> 
      <groupId>org.jboss.arquillian</groupId> 
      <artifactId>arquillian-bom</artifactId> 
      <version>1.1.12.Final</version> 
      <scope>import</scope> 
      <type>pom</type> 
     </dependency> 
    </dependencies> 
</dependencyManagement> 


<dependencies> 
    <dependency> 
     <groupId>javax</groupId> 
     <artifactId>javaee-api</artifactId> 
     <version>7.0</version> 
     <scope>provided</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.apache.tomee</groupId> 
     <artifactId>arquillian-openejb-embedded</artifactId> 
     <version>7.0.2</version> 
     <scope>test</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.jboss.arquillian.junit</groupId> 
     <artifactId>arquillian-junit-container</artifactId> 
     <scope>test</scope> 
    </dependency> 

    <dependency> 
     <groupId>javax.faces</groupId> 
     <artifactId>javax.faces-api</artifactId> 
     <version>2.2</version> 
     <scope>provided</scope> 
    </dependency> 

    <dependency> 
     <groupId>org.primefaces</groupId> 
     <artifactId>primefaces</artifactId> 
     <version>6.0.13</version> 
    </dependency> 

    <dependency> 
     <groupId>org.primefaces.themes</groupId> 
     <artifactId>all-themes</artifactId> 
     <version>1.0.10</version> 
    </dependency> 

    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.12</version> 
     <scope>test</scope> 
    </dependency> 

</dependencies> 

BackingBean:

import javax.faces.view.ViewScoped; 
import javax.inject.Named; 
import java.io.Serializable; 

@Named 
@ViewScoped 
public class AnotherBean implements Serializable { 

    public String doTest() 
    { 
     System.out.println("test"); 
     return "test"; 
    } 
} 

testBean就

@RunWith(Arquillian.class) 
public class TestAgain { 

    @Deployment 
    public static JavaArchive createDeployment() { 
     return ShrinkWrap.create(JavaArchive.class, "test.jar") 
       .addClass(AnotherBean.class) 
       .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); 
    } 

    @Inject 
    AnotherBean anotherBean; 

    @Test 
    public void doTest() 
    { 
     Assert.assertEquals(anotherBean.doTest(), "test"); 
     anotherBean.doTest(); 
    } 
} 

UPDATE

如果我變化率T他@Deployment到:

@Deployment 
    public static WebArchive createDeployment() { 
     return ShrinkWrap.create(WebArchive.class, "test.jar") 
       .addClass(AnotherBean.class) 
       .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); 
    } 

我得到:在測試

javax.enterprise.inject.UnsatisfiedResolutionException: Api type [AnotherBean] is not found with the qualifiers 
Qualifiers: [@javax.enterprise.inject.Default()] 
for injection into Field Injection Point, field name : anotherBean, Bean Owner : [null] 

回答

0

我們的帽子類似的困難@ViewScoped豆。我們通過在自己的測試中創建注入的bean來解決這個問題。

Bean實例本身是在測試中創建的,然後通過使用反射將所有依賴關係插入到該實例中。這適用於豆類,entitymanger等

@RunWith(Arquillian.class) 
public class ViewControllerTest { 
@Inject private OtherBean otherBean; 

private ViewController viewController; 


@Deployment 
public static WebArchive createDeployment() { 
    return WebArchiveFactory.getDefaultWebarchArchive(); 
} 

@Before 
public void setup() throws Exception { 
    viewController = new ViewController(); 
    TestHelper.setFacesContext(); // provide FacesContextMock 
    TestHelper.inject(viewController, "otherBean", otherBean); 
} 
} 

隨着TestHelper看起來像這樣

public class TestHelper { 

public static void inject(Object bean, 
          String fieldName, 
          Object fieldValue) throws Exception { 
    if (null == bean) { 
    throw new IllegalArgumentException("Bean must not be null"); 
    } 
    Field field; 
    try { 
    field = bean.getClass().getDeclaredField(fieldName); 
    } catch (NoSuchFieldException e) { 
    log.log(Level.SEVERE, "Could not find field for injection: " + fieldName); 
    throw e; 
    } 
    field.setAccessible(true); 
    field.set(bean, fieldValue); 
} 
} 
0

最後我不得不解決此問題,以良好的老式黑客。我發現原始WebBeans context with scope type annotation @ViewScoped does not exist within current thread來自org.apache.webbeans.container.BeanManagerImpl的來源。我在測試資源中創建了這個類,然後我做了一些修改來解決這個問題。

最終爲我的測試我不關心範圍。我測試的方法運行並返回正確的邏輯/數據。所以在類中它會檢查bean所在的作用域的類型並拋出異常。我只是檢查它是否在Viewscoped,如果是這樣,將其更改爲Dependent。這然後允許我的測試工作。

不是最好的解決方案,但它的工作原理。