Java 对 Hibernate 驱动的应用程序进行单元测试?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/400338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:14:02  来源:igfitidea点击:

Unit testing a Hibernate driven application?

javaunit-testinghibernatejunit

提问by James McMahon

This may be a naive question, but I am new to both the junit and hibernate frameworks and I was wondering what the best way to go about unit testing an application that is largely calls to hibernate, or if it is even necessary to do so?

这可能是一个幼稚的问题,但我对 junit 和 hibernate 框架都不熟悉,我想知道对主要调用 hibernate 的应用程序进行单元测试的最佳方法是什么,或者是否有必要这样做?

What is the best practice here?

这里的最佳做法是什么?

EDIT:
Spring seems to be the big suggestion here. Unfortunately this may be alittle too much to bite off for one project. Junit, Hibernate and Spring are all new to me, and while they are all technologies I want to get under my belt, I think trying to incorporate them all into one project may be too overwhelming for me.

编辑:
Spring 似乎是这里的重要建议。不幸的是,这对于一个项目来说可能有点太多了。Junit、Hibernate 和 Spring 对我来说都是新的,虽然它们都是我想要掌握的技术,但我认为尝试将它们全部合并到一个项目中可能对我来说太过分了。

Links to tutorials and/or book suggestions are welcome.

欢迎提供教程和/或书籍建议的链接。

回答by duffymo

Sure, you'd unit test your persistence tier if it wasn't written in Hibernate, wouldn't you?

当然,如果你的持久层不是用 Hibernate 编写的,你会对其进行单元测试,不是吗?

Create a given persistence interface that's implemented using Hibernate, instantiate some sample objects, perform CRUD operations, and ask JUnit to assert that the operations were successful. Same as any other class.

创建使用 Hibernate 实现的给定持久性接口,实例化一些示例对象,执行 CRUD 操作,并要求 JUnit 断言操作成功。与任何其他类相同。

回答by duffymo

Best practice? I use Spring and make all my tests transactional. I perform the test and rollback all the changes so I don't change the state of the database.

最佳实践?我使用 Spring 并使我所有的测试都是事务性的。我执行测试并回滚所有更改,因此我不会更改数据库的状态。

回答by Fortyrunner

You could use Spring to help here.

您可以使用 Spring 来提供帮助。

It has a great unit test framework, you can use it to test CRUD ops and then rollback changes - great if you don't have the capability to reload a database every time.

它有一个很棒的单元测试框架,你可以用它来测试 CRUD 操作,然后回滚更改——如果你没有每次都重新加载数据库的能力,那就太好了。

回答by Raymond Roestenburg

As for best practices:

至于最佳实践:

use an embedded database for running your tests if possible, so that you don't need a full deployed relational database just to run your tests (locally, or on your continuous build server if you have one). That way you also don't need to (necessarily) worry about rolling back etc, you can just recreate the database when you need to. Testing with an embedded database doesnt test peculiarities that could come up when you use your specific production database, but it does test your code, which should suffice.

如果可能,请使用嵌入式数据库来运行您的测试,这样您就不需要完全部署的关系数据库来运行您的测试(在本地,或者在您的持续构建服务器上,如果您有)。这样你也不需要(必然)担心回滚等,你可以在需要时重新创建数据库。使用嵌入式数据库进行测试不会测试您使用特定生产数据库时可能出现的特性,但它确实会测试您的代码,这应该就足够了。

You can also use DbUnit, an extension to JUnit, to easily fill the database with expected rows and put it in a known state, before you run your Hibernate tests.

在运行 Hibernate 测试之前,您还可以使用DbUnit(JUnit 的扩展)轻松地用预期的行填充数据库并将其置于已知状态。

回答by jon077

I like to use a in memory hsqldb for testing. The process for each hibernate POJO is:

我喜欢使用内存中的 hsqldb 进行测试。每个hibernate POJO的流程是:

  1. Create the object
  2. Persist it to the DB
  3. Clear the session
  4. Get it from the DB
  5. Assert the objects are equal.
  1. 创建对象
  2. 坚持到数据库
  3. 清除会话
  4. 从数据库中获取
  5. 断言对象相等。

For DAOs, I create and persist enough objects to accurately test the methods, then run the tests and delete the objects as necessary to not intefere with other tests.

对于 DAO,我创建并持久化了足够多的对象以准确测试方法,然后运行测试并根据需要删除对象,以免干扰其他测试。

回答by bpapa

Keep in mind the difference between unit testing and integration testing.

请记住单元测试和集成测试之间的区别。

Unit tests should be testing code without any outside dependencies. These dependencies are mocked using a framework like, for example, JMock.

单元测试应该是没有任何外部依赖的测试代码。这些依赖项是使用框架模拟的,例如 JMock。

Integration tests are important too but the major drawback of them is that they take a long time to run. You can run thousands of true unit tests in a couple of seconds, but it's not the same with integration tests.

集成测试也很重要,但它们的主要缺点是它们需要很长时间才能运行。您可以在几秒钟内运行数千个真正的单元测试,但这与集成测试不同。

Depending on the size of your project/development team you might want to prioritize true unit tests over integration tests. Both style of tests are important but if you are pressed for resources, just going with Unit testing may be a better idea.

根据您的项目/开发团队的规模,您可能希望将真正的单元测试优先于集成测试。两种测试风格都很重要,但如果您需要资源,那么只使用单元测试可能是一个更好的主意。

I wrote an application by myself that unit tested the Web (with Spring MVC this is easy) and Service layers, as well as domain objects. But I left the DAO alone because I didn't want to write a bunch of slow integration tests. If I had more people on staff I would have gone with integration tests as well, but in this case I didn't feel the time spent would be worth it.

我自己编写了一个应用程序,它对 Web(使用 Spring MVC 这很容易)和服务层以及域对象进行了单元测试。但是我没有考虑 DAO,因为我不想编写一堆缓慢的集成测试。如果我有更多的员工,我也会进行集成测试,但在这种情况下,我觉得花费的时间不值得。

回答by kamal.gs

Hibernate source includes a lot of unit tests, I would recommend going through those and adapting a similar approach.

Hibernate 源代码包含许多单元测试,我建议您通过这些测试并采用类似的方法。

You can also look at the CaveatEmptorwhich the sample application developed for the book "Java Persistence with Hibernate"

您还可以查看示例应用程序为“Java Persistence with Hibernate”一书开发的CaveatEmptor

回答by Douglas Squirrel

Write a simple layer that passes requests to Hibernate. Then use a mocking library like EasyMockor JMockto assert that your Hibernate-veneer layer is correctly called by your application classes. This is nicely described in the partially-complete JMock book(scroll down to the test smell "everything is mocked").

编写一个简单的层,将请求传递给 Hibernate。然后使用像EasyMockJMock这样的模拟库来断言您的应用程序类正确调用了 Hibernate-veneer 层。这在部分完整的JMock 书中有很好的描述(向下滚动到测试气味“一切都被嘲笑”)。

回答by Sathish

If you're using Hibernate for Domain rich models, Unit testing domain logic is as simple as testing a POJO and Hibernate doesn't get in your way. The only caveat here is, For bidirectional mappings, you might have to set the object on both sides for unit tests.

如果您将 Hibernate 用于域丰富模型,单元测试域逻辑就像测试 POJO 一样简单,而且 Hibernate 不会妨碍您。这里唯一的警告是,对于双向映射,您可能必须在两侧设置对象以进行单元测试。

Integration testing with database is generally not done for simple mappings. However it is suggested in the case of exquisite mappings like Single table inheritance etc. The only thing to remember here is, you may have to explicitly flush to database sometimes.

对于简单的映射,通常不使用数据库进行集成测试。但是,建议在诸如单表继承等精细映射的情况下使用。这里唯一要记住的是,有时您可能必须显式刷新到数据库。

回答by GlenPeterson

Two cases are easy to test:

两种情况很容易测试:

  1. When practical, perform your various calculations and transformations in functions that don't know about saving or loading entities. If you can make these pure functions, so much better.

  2. For functions that only save to the database without reading from it, you can choose not to save when testing.

  1. 在可行的情况下,在不知道保存或加载实体的函数中执行各种计算和转换。如果你能做出这些纯函数,那就更好了。

  2. 对于只保存到数据库而不读取的函数,测试时可以选择不保存。

The simplest (crudest) way to do #2 is by adding a reallyUpdateparameter to the function, then surrounding each "save" call with:

做#2 的最简单(最原始)的方法是向reallyUpdate函数添加一个参数,然后用以下内容包围每个“保存”调用:

if (reallyUpdate) {
    HibernateUtil.saveOrUpdate(theThing);
}

For me these were the lowest hanging fruit.

对我来说,这些是悬而未决的果实。