2012-05-28 11 views
5

Ich habe einen Lebenszyklus Problem einige Testsuite mit JUnit tun.JUnit Lebenszyklus

Um handliche JPA 2.0 Einheit zu schreiben testet Als Java-Entwickler Ich möchte einmal eine EntityManagerFactory Instanz

  • initialisieren, bevor alle Tests Suiten. Ich erreiche das Objekt durch die Anmerkung @BeforeClass mit
  • eine EntityManager-Instanz instanziiert und eine neue Transaktion vor jedem Testfall starten und die Transaktion gestartet wie AOP Rollback vor/nach oder um Rat
  • Lage sein, jede auf Make-up/Abreißvorgänge vorher/nachher in jeder abgeleiteten Testsuite

Ich habe JUnit Tests viel geschrieben. Aber in einem solchen Fall habe ich Probleme mit dem zweiten und dritten Punkt auf der Liste.

Bitte werfen Sie einen Blick der folgenden Testsuite Beispiele:

Eine abstrakte Testsuite:

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

} 

einer abgeleiteten Testsuite:

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

} 

Wegen nicht näher bezeichnet Reihenfolge der JUnit-Lebenszyklus-Annotationen Die NullPointerException nimmt einen Platz in th ein Die Methode setUp() in der abgeleiteten Klasse. Es ist klar für mich.

Ist es möglich, das Ziel zu bekommen, ohne die Injektion Start/rollbacking Transaktionscode in jedem setUp()/tearDown() -Methoden jeder abgeleiteten Testsuite Klasse von Hand? Oder gibt es vielleicht ein alternatives JUnit-Mittel oder Test-Framework, das eine einfache Möglichkeit bietet, meine Bedürfnisse auszudrücken?

Vielen Dank im Voraus.

Antwort

2

Wie gefallen Ihnen die Idee Google Guice der Verwendung der Entity-Manager und Transaktionen in Ihre Testmethoden zu injizieren?

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(...)); 
     } 
} 

Es könnte eine Menge Aufwand in diesem Bereich vereinfachen.

+0

Ja, es ist eine gute Idee. Da Google Guice ein Lean-IoC ist, kann es ohne Auswirkungen von Code verwendet werden. einmal direkt von meinem Code und das zweite Mal von JUnit in Bezug auf JUnit Lebenszyklus - –

1

Warum rufen Sie nicht super.setUp() in setUp, super.setUpClass usw.? Was Sie tatsächlich tun, ist das Überschreiben der Methode der Unterklasse.

+0

Eigentlich war ich auf diese Weise, und als Ergebnis der Mutter 'setUp()' Methode wurde in einer Reihe während des Testlaufes aufgerufen zweimal tun. –

1

Betrachten Frühling mit Einmal Instanziierung eines nicht-statischen Rollback-Einheit-Manager und Transaktion zu behandeln. Selbst wenn Sie Spring nicht in Ihrer Anwendung verwenden, können Sie davon profitieren, wenn Sie Spring nur in Ihren Tests verwenden. Einzelheiten finden Sie in Abschnitt 9.3 von http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/testing.html.

+0

Ja, ich stimme Ihnen vollkommen zu. Es ist eine großartige handliche Alternative. Dieses spezielle Projekt ist so klein und einfach, dass ich es vermeide, Spring zu benutzen, und zu verstehen, was ich ablehne. Vielen Dank. –