如何在单元测试期间注入PersistenceContext?

时间:2023-01-21 12:08:25

This is my java class:

这是我的java类:

public class Finder {
  @PersistenceContext(unitName = "abc")
  EntityManager em;
  public boolean exists(int i) {
    return (this.em.find(Employee.class, i) != null);
  }
}

This is the unit test:

这是单元测试:

public class FinderTest {
  @Test public void testSimple() {
    Finder f = new Finder();
    assert(f.exists(1) == true);
  }
}

Testing fails with NullPointerException since Finder.em is not injected by anyone. How should I handle this situation properly? Does there any best practice exist?

由于Finder.em未被任何人注入,因此测试因NullPointerException而失败。我应该如何妥善处理这种情况?有没有最佳实践?

2 个解决方案

#1


9  

Without a container like Spring (or something like Unitils - which is Spring based), you will have to inject the entity manager manually. In that case, you could use something like this as base class:

如果没有像Spring这样的容器(或像Unitils这样的容器 - 基于Spring),则必须手动注入实体管理器。在这种情况下,您可以使用类似这样的基类:

public abstract class JpaBaseRolledBackTestCase {
    protected static EntityManagerFactory emf;

    protected EntityManager em;

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

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

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

    @After
    public void rollbackTransaction() {   
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        if (em.isOpen()) {
            em.close();
        }
    }
}

#2


3  

It depends on what you want to test. When you have complex business logic in your Finder class you may want to mock the EntityManager - using a mocking framework like EasyMock or Mockito - in order to unit test that logic.

这取决于你想要测试的内容。当你的Finder类中有复杂的业务逻辑时,你可能想要使用像EasyMock或Mockito这样的模拟框架来模拟EntityManager,以便对该逻辑进行单元测试。

Now since that's not the case I suspect you want to test the persistency of the Employee entity (this is often referred to as integration testing). This requires the use of a database. To make testing easy and keep your tests portable you can use an in-memory database like HSQLDB for this purpose. In order to start HSQLDB, create a persistence context and inject this context into your Finder class it's advisable to use an IoC framework like Spring.

现在,因为不是这种情况,我怀疑你想要测试Employee实体的持久性(这通常被称为集成测试)。这需要使用数据库。为了简化测试并保持测试的可移植性,您可以使用内存数据库(如HSQLDB)来实现此目的。为了启动HSQLDB,创建一个持久化上下文并将此上下文注入到Finder类中,建议使用像Spring这样的IoC框架。

There are tons of tutorials on the internet that explain how to use JPA/Spring/HSQLDB. Take a look at this example project: Integration testing with Maven 2, Spring 2.5, JPA, Hibernate, and HSQLDB

互联网上有大量的教程解释了如何使用JPA / Spring / HSQLDB。看一下这个示例项目:使用Maven 2,Spring 2.5,JPA,Hibernate和HSQLDB进行集成测试

#1


9  

Without a container like Spring (or something like Unitils - which is Spring based), you will have to inject the entity manager manually. In that case, you could use something like this as base class:

如果没有像Spring这样的容器(或像Unitils这样的容器 - 基于Spring),则必须手动注入实体管理器。在这种情况下,您可以使用类似这样的基类:

public abstract class JpaBaseRolledBackTestCase {
    protected static EntityManagerFactory emf;

    protected EntityManager em;

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

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

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

    @After
    public void rollbackTransaction() {   
        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        if (em.isOpen()) {
            em.close();
        }
    }
}

#2


3  

It depends on what you want to test. When you have complex business logic in your Finder class you may want to mock the EntityManager - using a mocking framework like EasyMock or Mockito - in order to unit test that logic.

这取决于你想要测试的内容。当你的Finder类中有复杂的业务逻辑时,你可能想要使用像EasyMock或Mockito这样的模拟框架来模拟EntityManager,以便对该逻辑进行单元测试。

Now since that's not the case I suspect you want to test the persistency of the Employee entity (this is often referred to as integration testing). This requires the use of a database. To make testing easy and keep your tests portable you can use an in-memory database like HSQLDB for this purpose. In order to start HSQLDB, create a persistence context and inject this context into your Finder class it's advisable to use an IoC framework like Spring.

现在,因为不是这种情况,我怀疑你想要测试Employee实体的持久性(这通常被称为集成测试)。这需要使用数据库。为了简化测试并保持测试的可移植性,您可以使用内存数据库(如HSQLDB)来实现此目的。为了启动HSQLDB,创建一个持久化上下文并将此上下文注入到Finder类中,建议使用像Spring这样的IoC框架。

There are tons of tutorials on the internet that explain how to use JPA/Spring/HSQLDB. Take a look at this example project: Integration testing with Maven 2, Spring 2.5, JPA, Hibernate, and HSQLDB

互联网上有大量的教程解释了如何使用JPA / Spring / HSQLDB。看一下这个示例项目:使用Maven 2,Spring 2.5,JPA,Hibernate和HSQLDB进行集成测试