2012-04-10 12 views
6

Uso Arquillian para probar un bean de sesión sin estado que tiene una interfaz local y remota explícita. Pero en la prueba, Arquillian no "inyecta" nada en un campo que tiene el tipo de interfaz local, pero funciona para la interfaz remota.Explicite Local EJB no inyectado con Arquillian

@Stateless 
public class TestServiceImpl implements TestServiceLocal, TestServiceRemote { 
    public String greet() { 
     return "hallo"; 
    } 
} 

La interfaz remota:

@Remote 
public interface TestServiceRemote { 
    public String greet(); 
} 

La interfaz local:

@Local 
public interface TestServiceLocal { 
    public String greet(); 
} 

Y esta es la prueba:

@RunWith(Arquillian.class) 
public class GenericEntityDaoEjbIntegrationTest { 

    @Deployment 
    public static JavaArchive createTestArchive() 
        throws UnsupportedEncodingException { 
     return ShrinkWrap.create(JavaArchive.class, "test.jar") 
       .addClasses(
         TestServiceLocal.class, 
         TestServiceRemote.class, 
         TestServiceImpl.class); 
    } 

    @EJB 
    private TestServiceLocal testServiceLocal; 

    @EJB 
    private TestServiceRemote testServiceRemote; 

    //Will Fail 
    @Test 
    public void testTestServiceLocal() { 
     assertNotNull(this.testServiceLocal); 
    } 

    //Success  
    @Test 
    public void testTestServiceRemote() { 
     assertNotNull(this.testServiceRemote); 
    }  
} 

estoy usando Arquillian-glassfish-embedded 1.0.0.CR2, glassfish-embedde d-3.1 y todo-junit-contenedor Arquillian 1.0.0.CR5 La parte pertinente de mi pom es:

<!-- arquillian test --> 
    <dependency> 
     <groupId>org.jboss.arquillian.junit</groupId> 
     <artifactId>arquillian-junit-container</artifactId> 
     <version>1.0.0.CR5</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.jboss.arquillian.container</groupId> 
     <artifactId>arquillian-container-spi</artifactId> 
     <version>1.0.0.CR5</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.jboss.arquillian.container</groupId> 
     <artifactId>arquillian-glassfish-embedded-3.1</artifactId> 
     <version>1.0.0.CR2</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.extras</groupId> 
     <artifactId>glassfish-embedded-all</artifactId> 
     <version>3.1</version> 
     <scope>test</scope> 
    </dependency> 

Esta es la parte relevante del archivo de registro (que no contiene ninguna excepción):

10.04.2012 15:38:16 com.sun.ejb.containers.BaseContainer initializeHome 
INFO: Portable JNDI names for EJB TestServiceImpl : [java:global/test/TestServiceImpl!de.test.service.TestServiceRemote, java:global/test/TestServiceImpl!de.test.service.TestServiceLocal] 
10.04.2012 15:38:16 com.sun.ejb.containers.BaseContainer initializeHome 
INFO: Glassfish-specific (Non-portable) JNDI names for EJB TestServiceImpl : [de.test.service.TestServiceRemote, de.test.service.TestServiceRemote#de.test.service.TestServiceRemote] 
10.04.2012 15:38:16 com.sun.enterprise.web.WebApplication start 
INFO: WEB0671: Loading application [test] at [/test] 
10.04.2012 15:38:16 org.glassfish.deployment.admin.DeployCommand execute 
INFO: test was successfully deployed in 11.844 milliseconds. 

¿Cuál es mi error? ¿Qué debo cambiar para obtener una instancia inyectada para la interfaz de configuración regional también?

Respuesta

12

Se puede utilizar uno de los siguientes:

  • añadir un archivo beans.xml al despliegue:

    return ShrinkWrap.create(JavaArchive.class, "test.jar") 
           .addClasses(
             TestServiceLocal.class, 
             TestServiceRemote.class, 
             TestServiceImpl.class) 
           .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); 
    

    Esto permite que el CDITestEnricher de Arquillian, que es mucho más capaz que el EJBTestEnricher. Puede manejar anotaciones @Inject (obviamente), pero también anotaciones @Resource y @EJB (consulte la sección Inyección de recursos en la especificación CDI). Luego, el contenedor trata los campos anotados @EJB en su instancia de clase de prueba como puntos de inyección e inyecta las dependencias.

  • Especifique la propiedad mappedName para la anotación @EJB para el campo con el nombre JNDI portátil del bean desplegado. En su caso, se verá algo como:

    @EJB(mappedName="java:global/test/TestServiceImpl!com.acme.TestServiceLocal") 
    private TestServiceLocal testServiceLocal; 
    

    Usted tendrá que asegurarse de que el nombre JNDI portátil es la misma que la generada para su despliegue. Simplemente he especificado el que se generó para mi interfaz "com.acme.TestServiceLocal".

1

tratar de cambiar TestServiceImpl-> TestServiceBean parece que glassfish incrustadas tienen requisitos específicos a nombre del bean

5

Además de las respuestas también debe asegurarse de que usa la configuración correcta @Deployment es correcta. Para inyectar localmente debe asegurarse de tener @Deployment(testable=true) (tenga en cuenta que este es el valor predeterminado).

De Aquillian docs:

En el modo de contenedor: @Deployment (comprobable = true)

Como hemos mencionado anteriormente, tenemos que volver a empaquetar su @Deployment, añadiendo algunas clases de apoyo Arquillian , para ejecutar en contenedor. Esto nos da la capacidad de comunicarse con la prueba, enriquecer la prueba y ejecutar la prueba de forma remota. En este modo, la prueba se ejecuta en el contenedor remoto ; Arquillian usa este modo por defecto.

Consulte la Referencia completa del protocolo para obtener una descripción general de la salida esperada del proceso de empaquetado cuando proporciona un @Deployment.

modo Cliente: @Deployment (comprobable = false)

Ahora bien, este modo es la parte fácil. A diferencia del modo en contenedor que reempaca y anula la ejecución de la prueba, el modo as-client hace lo menos posible. No reempaca tu @Deployment ni reenvía la ejecución de la prueba a un servidor remoto. Su caso de prueba es ejecutándose en su JVM como se esperaba y puede probar el contenedor desde el exterior, según lo vean sus clientes. Lo único que hace Arquillian es controlar el ciclo de vida de su @Deployment.

Aquí hay un ejemplo llamando a un servlet usando el modo de cliente as.

Esto no ayuda al OP (tenían la configuración correcta) pero espero que ayude a los que llegan de Google, como yo lo hice.