如何使用 JPA 实现测试 DAO?
Posted
技术标签:
【中文标题】如何使用 JPA 实现测试 DAO?【英文标题】:How to test a DAO with JPA implementation? 【发布时间】: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 ,而不是我想要的......
【问题讨论】:
【参考方案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 容器无关。
【讨论】:
以上是关于如何使用 JPA 实现测试 DAO?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 EntityManager (JPA) 在 DAO 中实现 update() 方法?