2011-10-14 25 views
7

Estoy haciendo una pequeña investigación sobre Unit Testing de EJB 3.1. Al final, mi objetivo es producir una solución fácil de usar para Unit Testing EJB 3.1.Unit Testing EJB 3.1

  1. no tengo mucho conocimiento con grandes implementaciones EJB y por lo tanto me gustaría llegar en primer lugar algunas manos experimentadas (Usted) a la piscina justo en sus ideas sobre lo que es difícil en la unidad de prueba EJB.
  2. Con la investigación inicial que ya he hecho, puedo comprender las ventajas de utilizar marcos de burla para pruebas unitarias en lugar de utilizar contenedores integrados. Aunque ambos son buenos, los marcos de burla se destacan un poco más arriba cuando se trata de pruebas unitarias. Los contenedores integrados son, por supuesto, muy buenos y tienen sus propias ventajas, pero puede ser una fase diferente de prueba de la unidad. Todavía creo que debería haber algunas deficiencias, al menos en algunos escenarios, en el uso de dichos marcos que se pueden mejorar.

Espero que pueda hacer una solución completa para Unit Testing EJB que puedo compartir en este foro una vez hecho.

Gracias por su apoyo.

Respuesta

14

Mi consejo para usted sería no caer en la trampa común que veo, que es pensar que debe elegir entre burlarse y usar un contenedor EJB incrustado.

Puede usar ambos, debe usar ambos, y cuando le resulte difícil de usar, debe exigir una mejor compatibilidad y más características de su contenedor EJB.

Sin duda, encontrará personas en OpenEJB realmente de apoyo y más que feliz de agregar características para ayudar a obtener lo mejor de ambos mundos. Casi todas las características realmente buenas se han creado en torno a las solicitudes de los usuarios que intentan hacer cosas muy específicas y encontrarlas difíciles.

EJBContainer API estándar

package org.superbiz.stateless.basic; 

import junit.framework.TestCase; 

import javax.ejb.embeddable.EJBContainer; 

public class CalculatorTest extends TestCase { 

    private CalculatorBean calculator; 

    /** 
    * Bootstrap the Embedded EJB Container 
    * 
    * @throws Exception 
    */ 
    protected void setUp() throws Exception { 

     EJBContainer ejbContainer = EJBContainer.createEJBContainer(); 

     Object object = ejbContainer.getContext().lookup("java:global/simple-stateless/CalculatorBean"); 

     assertTrue(object instanceof CalculatorBean); 

     calculator = (CalculatorBean) object; 
    } 

fuente completo here

Este explora la ruta de clase y carga todos los granos.

n-escaneo, el enfoque más fácil de burla

enfoque ligeramente diferente donde se define todo en código. Obviamente, la burla es más fácil ya que puedes proporcionar implementaciones simuladas de frijoles donde sea necesario a voluntad.

@RunWith(ApplicationComposer.class) 
public class MoviesTest extends TestCase { 

    @EJB 
    private Movies movies; 

    @Resource 
    private UserTransaction userTransaction; 

    @PersistenceContext 
    private EntityManager entityManager; 

    @Module 
    public PersistenceUnit persistence() { 
     PersistenceUnit unit = new PersistenceUnit("movie-unit"); 
     unit.setJtaDataSource("movieDatabase"); 
     unit.setNonJtaDataSource("movieDatabaseUnmanaged"); 
     unit.getClazz().add(Movie.class.getName()); 
     unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)"); 
     return unit; 
    } 

    @Module 
    public EjbJar beans() { 
     EjbJar ejbJar = new EjbJar("movie-beans"); 
     ejbJar.addEnterpriseBean(new StatefulBean(MoviesImpl.class)); 
     return ejbJar; 
    } 

    @Configuration 
    public Properties config() throws Exception { 
     Properties p = new Properties(); 
     p.put("movieDatabase", "new://Resource?type=DataSource"); 
     p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver"); 
     p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb"); 
     return p; 
    } 

    @Test 
    public void test() throws Exception { 

     userTransaction.begin(); 

     try { 
      entityManager.persist(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992)); 
      entityManager.persist(new Movie("Joel Coen", "Fargo", 1996)); 
      entityManager.persist(new Movie("Joel Coen", "The Big Lebowski", 1998)); 

      List<Movie> list = movies.getMovies(); 
      assertEquals("List.size()", 3, list.size()); 

      for (Movie movie : list) { 
       movies.deleteMovie(movie); 
      } 

      assertEquals("Movies.getMovies()", 0, movies.getMovies().size()); 

     } finally { 
      userTransaction.commit(); 
     } 
    } 
} 

Full source here

El resultado final

Es tentador para centrarse en las diferencias entre los diferentes tipos de pruebas, etc., pero sin duda hay algo que decir acerca de un medio pragmático. Personalmente, no veo nada malo en poder mezclar los estilos de "unidad" e "integración" con la mayor fluidez posible.

Sin duda, es un objetivo admirable. Las ideas y solicitudes de características para acercarnos son bienvenidas.

+0

Hola David, muchas gracias por su respuesta. También estaba pensando en mezclar ambos enfoques, lo que ayudaría a cosechar los beneficios de ambos enfoques. – Bala

5

En realidad, hay dos tipos diferentes de pruebas es posible que desee considerar la posibilidad (no exclusivo):

  • Unidad de Pruebas: Sus EJB son POJOs al final del día y por lo tanto usted puede utilizar su preferida marco de pruebas unitarias (p. ej., JUnit) y también un marco de burla como Mockito o EasyMock.
  • Pruebas de integración: aquí desea probar los EJB como si estuvieran en el contenedor (no de forma aislada) y, por lo tanto, debe emular ese contenedor de alguna manera. Todavía puede usar su marco de prueba unitario para codificar sus pruebas (por ejemplo, JUnit), pero ahora está probando cómo se comportan estos EJB en el contenedor e interactúan con otros colaboradores (por ejemplo, otros EJB) que puedan tener. Para esto, recomendaría Arquillian
+0

Gracias por sus entradas. Básicamente me enfoco en hacer que las pruebas unitarias sean más simples con las características para hacerlo tan elegante y fácil para el desarrollador. Pero, como también lo mencionó, un mejor enfoque sería una combinación de pruebas UT e Integración usando contenedores incrustados ya que 2 fases de UT parecen un buen enfoque. – Bala

3

Puede usar la aguja para las pruebas unitarias de los componentes de Java EE.

Needle es un marco liviano para probar componentes de Java EE fuera del contenedor de forma aislada. Reduce el código de configuración de prueba al analizar las dependencias y la inyección automática de objetos simulados.

http://needle.spree.de