2017-01-27 2 views
0

Wir sind dabei unsere JavaEE App von Weblogic 10.3.6 auf Weblogic 12.2.1.2 zu migrieren. Als Teil dieser Migration ändern wir unsere JSF-Managed-Beans so, dass sie CDI-Annotationen anstatt der Standard-JSF-Annotationen verwenden. @ManagedBean bis @Named und javax.faces.bean.ViewScoped bis javax.faces.view.ViewScoped. Dies hat sich mit nur geringen Problemen als erfolgreich erwiesen. Ich habe jedoch ein großes Problem damit, unsere Tests laufen zu lassen. Die Tests schlagen mit dem folgenden Fehler fehl:Arquillian testet JSF mit CDI - CDI Scope Ausgabe

Ich habe mehrere verschiedene Container (eingebettete und remote) versucht, aber immer noch denselben Fehler erhalten. Jede Hilfe würde sehr geschätzt werden.

Ich verwende Arquillian mit folgenden pom.xml Abhängigkeiten:

<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

Wenn ich t ändern er @Deployment zu:

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

I Get:

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] 

Antwort

0

Wir Hut ähnliche Schwierigkeiten bei der Prüfung @ViewScoped Bohnen. Wir haben dies gelöst, indem wir die Bohne mit ihren Injektionen im Test selbst erstellt haben.

Die Bean-Instanz selbst wird im Test erstellt und alle Abhängigkeiten werden dann durch Reflektion in diese eingefügt. Dies funktioniert mit Bohnen, entitymanger etc

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

Mit TestHelper wie diese suchen

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

Am Ende habe ich, um dieses Problem mit einem guten alten Hack arbeiten musste. Ich habe die Quelle für org.apache.webbeans.container.BeanManagerImpl gefunden, wo das Original WebBeans context with scope type annotation @ViewScoped does not exist within current thread herkommt. Ich habe diese Klasse in meinen Testquellen erstellt und dann einige Änderungen vorgenommen, um das Problem zu umgehen.

Letztendlich ist mir bei meinen Tests der Umfang egal. Ich teste, dass die Methoden ausgeführt werden und die richtige Logik/Daten zurückgeben. Also in der Klasse geht es und überprüft, welche Art von Bereich der Bean ist und löst die Ausnahme aus. Ich habe einfach überprüft, ob es in Viewscoped war und wenn es so geändert wurde, Dependent. Dies erlaubte dann meine Tests zu arbeiten.

Nicht die beste Lösung, aber es funktioniert.