您如何对使用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,因为我试图摆脱这种方法。
感谢您的帮助。
答案 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();