JUnit生命周期

时间:2012-05-28 21:52:40

标签: java testing junit

我在使用JUnit做一些测试套件时遇到了生命周期问题。

为了编写方便的JPA 2.0单元测试 作为Java开发人员 我想:

  • 在所有测试套件之前初始化一次EntityManagerFactory实例。我通过使用@BeforeClass annotation
  • 来实现该对象
  • 实例化一个EntityManager实例并在每个测试用例之前启动一个新事务,并在建议之前/之后或周围回滚像AOP这样的已启动事务
  • 能够在任何衍生测试套件之前/之后进行任何设置/拆卸操作

我一直在编写JUnit测试。但在这种情况下,我对列表中的第二项和第三项有疑问。

请查看以下测试套件示例:

抽象测试套件

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

}

派生测试套件

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

}

由于JUnit生命周期注释的未指定顺序,NullPointerException在派生类的setUp()方法中占有一席之地。这对我来说很清楚。

是否有可能在不手动地在任何派生测试套件类的每个setUp()/ tearDown()方法中注入启动/回滚事务代码的情况下获得目标? 或者,是否有替代JUnit意味着或测试框架可以提供一种简单的方式来表达我的需求?

提前致谢。

3 个答案:

答案 0 :(得分:2)

您如何使用Google Guice将实体管理器和事务注入测试方法?

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

这可以简化这方面的大量工作。

答案 1 :(得分:1)

为什么不在super.setUp()setUp等中致电super.setUpClass?你实际做的是覆盖子类的方法。

答案 2 :(得分:1)

考虑使用Spring来处理非静态实体管理器和事务回滚的一次性实例化。即使您没有在应用程序中使用Spring,也可以在测试中使用它。有关详细信息,请参阅http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/testing.html的第9.3节。