3

您将如何对使用 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) { .. }
}

如果我无法访问数据库,您将如何对 calculateOrderTotal 方法进行单元测试?我不想实现 DAO,因为我正试图摆脱这种方法。

谢谢你的帮助。

4

3 回答 3

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 实例可能非常乏味,但它确实会使未来的测试更快。

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

于 2010-09-30T20:01:33.053 回答
4

你试过 OpenEjb 吗?- 如果您在嵌入式模式下设置,您几乎可以从 Eclipse 运行单元测试。我之前已经为单元测试模拟了实体管理器注入等,但后来变得乏味。使用 openejb,您可以用更少的设置来完成。http://openejb.apache.org/

于 2010-09-30T22:28:39.380 回答
0

这就是我所做的:

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

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

em.getTransaction().begin();
myEjb.doSomething(x, y);
em.getTransaction().commit();
于 2010-09-30T21:15:29.087 回答