如何在使用JPA2时对EJB进行unit testing?

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

@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,因为我试图摆脱这种方法。

谢谢你的帮助。

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) 

因此,在每次测试中,您都可以创建完成计算代码某些方面所需的顺序。 您可能会有许多此类测试可以推动计算的所有边缘和角落情况。

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

我也赞成做早期的集成测试 – 你会发现另外一类错误。

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

这是我做的:

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

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

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