【问题标题】:How to test a DAO with JPA implementation?如何使用 JPA 实现测试 DAO?
【发布时间】:2011-01-30 01:05:10
【问题描述】:

我来自 Spring 阵营,我不想使用 Spring,正在迁移到 JavaEE6, 但我在测试 DAO + JPA 时遇到问题,这是我的简化示例:

public interface PersonDao
{
  public Person get(long id);
}

这是一个很基础的DAO,因为我是Spring出来的,相信DAO还是有它的价值的,所以决定加一个DAO层。

public class PersonDaoImpl implements PersonDao , Serializable
{
  @PersistenceContext(unitName = "test", type = PersistenceContextType.EXTENDED)
  EntityManager entityManager ;

  public PersonDaoImpl()
  {
  }

  @Override
  public Person get(long id)
  {
    return entityManager .find(Person.class , id);
  }
}

这是一个 JPA 实现的 DAO,我希望 EE 容器或测试容器能够注入 EntityManager(就像 Spring 一样)。

public class PersonDaoImplTest extends TestCase
{
  @Inject 
  protected PersonDao personDao;

  @Override
  protected void setUp() throws Exception
  {
    //personDao = new PersonDaoImpl();
  }

  public void testGet()
  {
    System.out.println("personDao = " + personDao); // NULL !
    Person p = personDao.get(1L);
    System.out.println("p = " + p);
  }
}

这是我的测试文件。

好的,问题来了: 因为 JUnit 不理解 @javax.inject.Inject ,所以 PersonDao 将无法注入,测试将失败。

如何找到能够将 EntityManager 注入 PersonDaoImpl 并将 PersonDaoImpl 注入到 TestCase 的 PersonDao 的测试框架?

我试过 unitils.org ,但找不到这样的样本,它只是直接将 EntityManagerFactory 注入到 TestCast ,而不是我想要的......

【问题讨论】:

    标签: java testing jpa dao cdi


    【解决方案1】:

    因为我来自Spring,我相信DAO还是有它的价值的,所以我决定加一个DAO层。

    我真的不明白 Spring 与此有什么关系。我不同意as I wrote in a previous answer。对我来说,JPA 是一个 DAL(数据访问层),我看不出将数据访问层置于另一个数据访问层之上的意义。至少不是系统的。但是我们不要讨论这个。

    这是一个 JPA 实现的 DAO,我希望 EE 容器或测试容器能够注入 EntityManager(就像 Spring 一样)。

    如果您的 DAO 是像 CDI 托管 bean 这样的托管组件,那么 Java EE 容器应该能够在其中注入 EntityManager

    对于容器管理对象的单元测试,您不需要任何类型的容器。对于集成测试,您将需要某种容器,就像您对 Spring bean、Hibernate/JPA 实体、会话 bean、CDI 托管 bean 或任何其他类型的容器托管对象所做的那样。你可以use the EJB3.1 embeddable API in your tests。也可以看看Arquillian

    【讨论】:

    • 至于 JPA 是否杀死了 DAO,这取决于。在某些时候,您想在某处重构 JPA 代码,以便可以在其他地方重用它。那么还有什么比 DAO 更好的地方呢?
    • @BalusC 我不同意“系统地使用 DAO”,但我同意“这取决于”......但不完全是因为你给出的原因(我不是说你是错了,但我想看看你的例子的具体说明,我在可视化它时遇到了一些困难)。
    • 还没有,我还没有在实际项目中使用过 JPA,只是对它感兴趣。但我可以想象,每当你需要重复相同的一堆 JPA 代码行时,如果它超过 3~5 行代码左右,你想重构它,我还无法想象“正确”放置这些行的地方。它是 DAO 类吗?
    【解决方案2】:

    您也可以添加方法PersonDaoImpl.setEntityManager(EntityManager em),然后通过Persistence.createEntityManagerFactory("test").createEntityManager() 设置它。 这与 Java EE 容器无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 2010-12-21
      • 1970-01-01
      • 2015-05-24
      • 1970-01-01
      相关资源
      最近更新 更多