使用Hibernate / Spring / JUnit设置和清除复杂数据库状态

时间:2009-05-05 01:01:04

标签: java hibernate spring junit

我有一个类我是单元测试,需要相当广泛的数据库设置才能运行各个测试方法。这种设置需要很长时间:由于希望与手头的问题无关,我需要以编程方式而不是SQL转储来填充数据库。

我遇到的问题是拆除。如何轻松回滚在db setup阶段所做的所有更改?

我目前正在使用Hibernate + Spring Transactional Testing支持,这样我的各个测试方法都包含在事务中。

一种解决方案是在每个测试方法中进行数据库设置,以便自动回滚数据库设置。但是,测试方法将永远运行,因为每个方法都需要重新准备数据库。

还有其他想法吗?基本上,我正在寻找一种方法来运行我的数据库设置,运行我的单独测试(每个测试都包含在执行后回滚的事务中),然后回滚初始数据库设置。有关使其以Hibernate / Spring / Junit方式工作的任何想法吗?是否有一个Hibernate“drop all tables”等效命令?

8 个答案:

答案 0 :(得分:7)

您是否遇到了特定的数据库供应商?如果没有,您可以使用内存数据库,例如HSQLDB。当你完成测试后,你就扔掉了状态。这仅适用于在测试套件开始时表(在编程设置之前)表为空的情况。

您仍然需要创建表,但如果使用Hibernate整齐地映射所有内容,则可以使用hbm2ddl生成表。您所要做的就是将以下内容添加到 test 会话工厂定义中:

<session-factory>
    ...
    <property name="hibernate.hbm2ddl.auto">create</property>
    ...
</session-factory>

如果这个解决方案似乎适用,我可以详细说明。

答案 1 :(得分:0)

对于Junit 4,您可能需要查看@AfterClass注释。此注释将在测试完成时运行。

http://cwiki.apache.org/DIRxDEV/junit4-primer.html

答案 2 :(得分:0)

DNUnit应该在这方面帮助你。 如果愿意,您可以为每个单独的测试用例创建单独的数据集。

答案 3 :(得分:0)

DBUnit将对此有所帮助。理论上你可以关闭JDBC上的自动提交,但它会变得毛茸茸。最明显的解决方案是在运行测试之前使用DBUnit将数据设置为已知状态。如果由于某种原因你需要在测试运行后返回数据,你可以在运行所有测试的套件上查看@AfterClass,但通常认为设置测试然后运行它们是更好的做法,所以如果测试失败,那不仅仅是因为由于未能清理不同的测试而没有预设环境。您可以确保每个测试都直接设置其环境。

答案 4 :(得分:0)

您可能需要考虑的一个解决方案是在db拆卸中使用“手动”回滚或补偿事务。我想(如果它不是那么它应该是你的Hibernate实体的一个微不足道的附加组件)你的所有实体都有datetime create属性,指示它们何时被插入到表中。您的数据库设置方法应记录其他所有内容的时间。然后你有一个相当简单的db拆卸程序来删除在db setup中记录的时间后创建的所有实体。

当然,这不适用于数据库设置中的更新......但是如果您的更新数量有限,那么请考虑为此类数据保存原始图像,并在数据库拆除期间恢复它。

答案 5 :(得分:0)

如果您正在使用相对较小的数据库,并且使用可以相对快速地进行备份/导出的DBMS(如MS SQL Server),您可以考虑在测试之前创建数据库备份,然后在执行时恢复它所有测试都已完成。这使您可以设置开发/测试数据库并将其用作所有测试的起始状态。

我使用本机JDBC,执行''备份数据库''和'还原数据库''T-SQL中间测试,并且它运行得相当好。

但是,这种方法取决于在本地计算机上使用DBMS服务器(速度合理),您具有足够的权限(这应该不是问题),并且数据库的总大小不超过几十MB - 至少在我的经验中。

答案 6 :(得分:0)

您是否有必要连接数据库才能运行单元测试?听起来重构类可能更容易,这样您就可以模拟与数据库的交互。您可以模拟类(有一些例外)以及与EasyMock(www.easymock.org)的接口。

如果您的类依赖于连接数据库中复杂的预先存在状态,则使用模拟编写更快的执行测试可能会更容易。我们不知道您的项目的大小是多少或者您的测试运行的频率,但执行时间可能需要考虑,特别是在大型项目中。

答案 7 :(得分:0)

Hibernate有一个整洁的小功能,严重缺乏记录和未知。您可以在生成数据库模式之后立即在SessionFactory创建期间执行SQL脚本,以在新数据库中导入数据。您只需在类路径根目录中添加名为import.sql的文件,并将create或create-drop设置为hibernate.hbm2ddl.auto属性。

http://in.relation.to/Bloggers/RotterdamJBugAndHibernatesImportsql