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

发布于 2024-09-25 14:35:55 字数 524 浏览 0 评论 0原文

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

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

以及 orderEJB

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

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

感谢您的任何帮助。

How would you go about unit testing an EJB that uses JPA? For example, if I have an Order entity and and OrderEJB that is supposed to calculate the total of an order (as defined below) how would I go about unit testing the EJB without touching the database? Also, how would you define values for your entities, so you can assert the expected calculation? Here is some example code below...

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

And an orderEJB

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

How would you go about unit testing the calculateOrderTotal method if I can't touch the database? I don't want to implement a DAO because I'm trying to move away from that approach.

Thanks for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

述情 2024-10-02 14:35:55

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

 calculateOrderTotal()

您有一些概念上的代码

 em.giveMeThisOrder(orderId)

,您只需模拟它即可。然后,您正在测试的业务逻辑将由模拟返回的内容驱动。关键是你必须使用一个好的模拟框架,例如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 实例可能非常乏味,但它确实会让未来的测试更快。

我也赞成进行早期集成测试——这样你会发现另一类错误。

Isn't the general theory that OrderEJB and Order and LineItem are (if we ignore the annotation) just POJO and therefore can be tested in stand-alone JUnit? We will need to mock EntityManager, and presumably in

 calculateOrderTotal()

you have some code that in concept goes

 em.giveMeThisOrder(orderId)

and you just mock this. The businesss logic you're testing then gets driven by what the Mock returns. The key to this is that you must use a good mocking framework, for example JMock. In any given test you say (obviusly not with this syntax):

 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)

and so in each test you create exactly the order you need to exercise some aspect of your calcualtion code. You may well have many such tests that push all the edge and corner cases of your calculation.

The key idea here is Unit Test implies no external dependency such as a Database. Integration Testing could use a real database. It can be a hassle to get your mocks right, creating those Order instances can be quite dull, but it does tend to make future testing much quicker.

I do also favour doing early integration testing - you find a whole other class of errors that way.

挽清梦 2024-10-02 14:35:55

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

Did you give OpenEjb a try? - If you setup in embedded mode you can pretty much run unit tests from eclipse. I have mocked out entity manager injections etc for unit testing before but then it gets tedious. With openejb you can do it with less setup. http://openejb.apache.org/

不必你懂 2024-10-02 14:35:55

这就是我所做的:

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

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

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

Here's what I do:

First you need to set up an in-memory database for your tests. It works just like a regular database, but it's not stored on disk. Both Derby and HsqlDB support this.

In your unit test, create an EntityManager manually, and inject it into your EJB instance. You'll probably need to keep a reference to the EntityManager so you can manage the transactions, like this:

em.getTransaction().begin();
myEjb.doSomething(x, y);
em.getTransaction().commit();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文