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

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

我遇到的问题是拆除。 如何轻松回滚数据库设置阶段所做的所有更改?

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

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

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

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

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

 ... create ...  

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

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

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

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

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

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

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

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

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

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

您是否有必要连接到数据库以运行unit testing? 听起来重构类可能更容易,以便您可以模拟与数据库的交互。 您可以模拟类(有一些例外)以及与EasyMock(www.easymock.org)的接口。

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

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

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