如何在使用JPA2时对EJB进行单元测试?

时间:2010-09-30 19:55:00

标签: java unit-testing java-ee jpa-2.0 ejb-3.1

您如何对使用JPA的EJB进行单元测试?例如,如果我有一个Order实体和OrderEJB,它应该计算一个订单的总和(如下定义),我将如何在不触及数据库的情况下对EJB进行单元测试?另外,您将如何定义实体的值,以便断言预期的计算?以下是一些示例代码...

@Entity
public class Order {
    @Id
    private long OrderId;
    private LineItem[] items;
}

订单EJB

@Stateless
public class OrderEJB {
    EntityManager em;
    public double calculateOrderTotal(long orderId) { .. }
}

如果我无法触摸数据库,您会如何进行unitOrderTotal方法的单元测试?我不想实现DAO,因为我试图摆脱这种方法。

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

OrderEJB和Order和LineItem的一般理论(如果我们忽略注释)只是POJO,因此可以在独立的JUnit中进行测试吗?我们需要模拟EntityManager,大概是在

 calculateOrderTotal()

你有一些概念上的代码

 em.giveMeThisOrder(orderId)

你只是嘲笑这个。您正在测试的业务逻辑然后由Mock返回的内容驱动。关键是你必须使用一个好的模拟框架,例如JMock。在任何给定的测试中,你说(显然没有这种语法):

 EntitiyManager mockEm = // create the mock
 mockEm.check(that you are called with and order Id of 73)
 mockEm.please( when someone calls giveMeThisOrder return then **this** particular order)

所以在每个测试中,您都可以精确地创建执行计算代码某些方面所需的顺序。您可能会有许多此类测试可以推动计算的所有边缘和边角情况。

这里的关键思想是单元测试意味着没有外部依赖,例如数据库。集成测试可以使用真实的数据库。让你的模拟正确可能很麻烦,创建那些Order实例可能会非常沉闷,但它确实会使未来的测试更快。

我也赞成进行早期集成测试 - 你会发现其他类错误。

答案 1 :(得分:4)

您是否尝试过OpenEjb? - 如果你在嵌入模式下设置,你几乎可以从eclipse运行单元测试。我曾经嘲笑实体经理注射等单位测试,但之后却变得单调乏味。使用openejb,您可以使用较少的设置来完成。 http://openejb.apache.org/

答案 2 :(得分:0)

这就是我的所作所为:

首先,您需要为测试设置内存数据库。它就像常规数据库一样工作,但它不存储在磁盘上。 Derby和HsqlDB都支持这一点。

在单元测试中,手动创建一个EntityManager,并将其注入EJB实例。您可能需要保留对EntityManager的引用,以便您可以管理事务,如下所示:

em.getTransaction().begin();
myEjb.doSomething(x, y);
em.getTransaction().commit();