2012-05-28 39 views
5

Tôi gặp vấn đề về vòng đời khi thực hiện một số bộ thử nghiệm với JUnit.JUnit vòng đời

Để viết có ích đơn vị JPA 2,0 kiểm tra Là một nhà phát triển Java Tôi muốn:

  • Khởi tạo một thể hiện EntityManagerFactory một lần trước khi tất cả các dãy phòng xét nghiệm. Tôi đạt được đối tượng bằng cách sử dụng chú giải @BeforeClass
  • Khởi tạo phiên bản EntityManager và bắt đầu giao dịch mới trước mỗi trường hợp thử nghiệm và quay lại giao dịch đã bắt đầu như AOP trước/sau hoặc xung quanh lời khuyên
  • Có thể thực hiện bất kỳ thiết lập nào/xé xuống các hoạt động trước/sau trong bất kỳ bộ thử nghiệm có nguồn gốc nào

Tôi đã viết rất nhiều bài kiểm tra JUnit. Nhưng trong trường hợp như vậy, tôi đã có vấn đề với các mục thứ hai và thứ ba từ danh sách.

Hãy xem những ví dụ kiểm tra bộ sau:

Một trừu tượng thử nghiệm bộ:

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

} 

Một bộ kiểm tra nguồn gốc:

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

} 

Do không xác định thứ tự của các chú thích vòng đời JUnit, NullPointerException diễn ra trong phương thức e setUp() trong lớp dẫn xuất. Rõ ràng với tôi.

Có thể lấy mục tiêu mà không cần tiêm mã giao dịch bắt đầu/rollback trong mỗi phương thức setUp()/tearDown() của bất kỳ lớp bộ thử nghiệm có nguồn gốc nào không? Hoặc, có thể, liệu có một khuôn khổ JUnit hoặc khung kiểm tra thay thế có thể cung cấp một cách dễ dàng để thể hiện nhu cầu của tôi không?

Xin cảm ơn trước.

Trả lời

2

Bạn thích ý tưởng sử dụng Google Guice để tiêm Trình quản lý đối tượng và Giao dịch vào các phương pháp thử nghiệm của bạn như thế nào?

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

Nó có thể đơn giản hóa rất nhiều nỗ lực trong lĩnh vực này.

+0

Vâng, đó là một ý tưởng hay. Vì Google Guice là một IoC gọn gàng, nó có thể được sử dụng mà không có tác động của mã. –

1

Tại sao bạn không gọi super.setUp() trong setUp, super.setUpClass v.v ...? Những gì bạn đang thực sự làm là ghi đè phương thức của lớp con.

+0

Thực ra tôi đã làm theo cách đó và kết quả là phương thức 'setUp()' được gọi hai lần liên tiếp trong khi chạy thử - một lần trực tiếp từ mã của tôi và lần thứ hai bởi JUnit liên quan đến vòng đời JUnit. –

1

Xem xét sử dụng Spring để xử lý việc khởi tạo một lần của trình quản lý đối tượng không phải tĩnh và rollback giao dịch. Ngay cả khi bạn không sử dụng Spring trong ứng dụng của bạn, bạn có thể hưởng lợi từ việc sử dụng nó chỉ trong các bài kiểm tra của bạn. Xem phần 9.3 của http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/testing.html để biết chi tiết.

+0

Có, tôi hoàn toàn đồng ý với bạn. Đó là một lựa chọn tiện lợi tuyệt vời. Dự án đặc biệt đó quá nhỏ và đơn giản nên tôi tránh sử dụng Spring, với sự hiểu biết những gì tôi từ chối. Cảm ơn. –

Các vấn đề liên quan