2012-05-28 23 views
5

Ho un problema durante il ciclo di vita con alcune suite di test con JUnit.JManuale del ciclo di vita

Per scrivere a portata di mano unità JPA 2.0 mette alla prova Come sviluppatore Java Voglio:

  • Inizializzare un'istanza EntityManagerFactory una volta prima di tutti i test suite. Raggiungo l'oggetto utilizzando l'annotazione @BeforeClass
  • Istanzia un'istanza EntityManager e avvia una nuova transazione prima di ogni caso di test e rollback della transazione avviata come AOP prima/dopo o intorno a consigli
  • Essere in grado di eseguire qualsiasi impostazione/operazioni di smontaggio prima/dopo in qualsiasi suite di test derivata

Ho scritto molto test JUnit. Ma in tal caso ho avuto problemi con il secondo e il terzo elemento della lista.

prega di dare un'occhiata dei seguenti esempi suite di test:

Una suite astratto prova:

public abstract class AbstractPersistenceTest { 

    protected static EntityManagerFactory emf; 
    protected EntityManager em; 

    @BeforeClass 
    public static void setUpClass() { 
     emf = Persistence.createEntityManagerFactory("test"); 
    } 

    @Before 
    public void setUp() { 
     em = emf.createEntityManager(); 
     em.getTransaction().begin(); 
    } 

    @After 
    public void tearDown() { 
     em.getTransaction().rollback(); 
     em.close(); 
    } 

    @AfterClass 
    public static void tearDownClass() { 
     emf.close(); 
    } 

} 

Una suite di test derivato:

public class EmployeeJpqlTest extends AbstractPersistenceTest { 

    private Employee john; 
    private Employee jack; 

    @Before 
    public void setUp() { 
     john = new Employee("John Doe", 1000); 
     jack = new Employee("Jack Line", 1010); 

     em.persist(john); 
     em.persist(jack); 
    } 

    @Test 
    public void itShouldRetrieveAllEmplloyees() { 
     TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e", 
       Employee.class); 
     List<Employee> employees = query.getResultList(); 

     assertArrayEquals(new Employee[] { john, jack }, employees.toArray()); 
    } 

    @Test 
    public void itShoulRetrieveAllEmployeeNames() { 
     TypedQuery<String> query = em.createQuery(
       "SELECT e.name FROM Employee e", String.class); 
     List<String> names = query.getResultList(); 

     assertArrayEquals(new String[] { john.getName(), jack.getName() }, 
       names.toArray()); 
    } 

} 

A causa della non specificata l'ordine delle annotazioni del ciclo di vita di JUnit la NullPointerException prende posto in th e metodo setUp() nella classe derivata. È chiaro per me.

È possibile ottenere l'obiettivo senza iniettare il codice di transazione di avvio/rollback in ogni metodo setUp()/tearDown() di una classe di suite di test derivata a mano? O forse esiste una media o una struttura di test JUnit alternativa che possa fornire un modo semplice per esprimere le mie esigenze?

Grazie in anticipo.

risposta

2

In che modo ti piace l'idea di utilizzare Google Guice per iniettare Entity Manager e Transactions nei tuoi metodi di test?

import com.google.inject.persist.Transactional; 
import javax.persistence.EntityManager; 

public class MyTest { 
     @Inject EntityManager em; 

     @Test 
     @Transactional 
     public void createNewPerson() { 
       em.persist(new Person(...)); 
     } 
} 

Potrebbe semplificare un grande sforzo in questo settore.

+0

Sì, è una buona idea. Poiché Google Guice è un IoC snello, può essere utilizzato senza impatto del codice. –

1

Perché non chiami super.setUp() in setUp, super.setUpClass ecc.? Quello che stai facendo in realtà sta scavalcando il metodo della sottoclasse.

+0

In realtà stavo facendo in questo modo e di conseguenza il metodo padre 'setUp()' è stato invocato due volte di fila durante l'esecuzione di test - una volta direttamente dal mio codice e la seconda volta da JUnit riguardo al ciclo di vita di JUnit. –

1

Considerare l'utilizzo di Spring per gestire l'istanziazione una tantum di un gestore di entità non statico e il rollback della transazione. Anche se non utilizzi Spring nella tua applicazione, potresti trarre vantaggio dall'utilizzarlo solo nei test. Vedere la sezione 9.3 di http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/testing.html per i dettagli.

+0

Sì, sono completamente d'accordo con te. È un'ottima alternativa a portata di mano. Quel particolare progetto è così piccolo e semplice, quindi evito di usare Spring, capendo cosa rifiuto. Grazie. –

Problemi correlati