JUnit:测试DAO - 回滚或删除

时间:2012-01-20 12:16:55

标签: java database unit-testing junit

我正在使用JUnit 4测试一个非常简单的java应用程序。“简单”我的意思是没有弹簧和没有休眠。我需要测试数据访问层(JDBCMySQL),我怀疑哪种方法更适合这种测试?在@Before上插入数据并在@After上删除或在@Before上创建一个交易并在@After上回滚?

谢谢!

5 个答案:

答案 0 :(得分:4)

交易有两个原因:

  • 写回/删除可能比回滚更贵
  • 错误幅度较小(您删除数据的代码可能有错误)

答案 1 :(得分:4)

我不同意使用MySQL以外的数据库,因为您可能会遇到测试中的平台差异,这些差异掩盖了代码与MySQL的问题。如果没有大量的重构,你的一些代码/ SQL甚至可能无法在另一个平台上运行。

但是,同意其他人关于使用事务而不是删除或更新来恢复状态。

一个警告:如果你正在使用过程,函数等,那些可以在内部执行COMMIT,这可能会破坏任何回滚JUnit更改的尝试。对您来说可能不是问题,但也许是其他人要记住的问题,特别是在处理从未考虑过单元测试的遗留数据库代码时。

答案 2 :(得分:2)

我还会在内存数据库或MySQL中的临时表中使用volatile,这些表是特定于连接的,并在连接关闭时自动删除。 我不会将事务用于此类测试,因为您可能希望实际测试事务本身。

答案 3 :(得分:1)

事务回滚更安全,因为测试数据库保持不变,即使测试方法和@After之前测试已停止。

但是,更好地提交和删除测试,因为在提交期间会针对新数据检查某些约束(延迟外键等),因此使用回滚时,您将无法测试某些内容。

所以这取决于你,但在大多数情况下,事务回滚是首选的选择(我也更喜欢)。

答案 4 :(得分:0)

无论我在哪里工作,不同的开发人员都喜欢不同的解决方案。

首先,由于以下原因,我不喜欢使用内存数据库

  1. 代码似乎超过了测试。我们找到了一个代码库,其中在内存中测试的表在实际数据库中不存在。
  2. 数据库不完全相同,如果你在内存中使用hsql,但你的主数据库是MySQL,那么语法,日期等等都会有所不同。我知道你可以使用ASCII Sql,但是你正在测试一些不是你要运行的东西。会有差异。
  3. 我更喜欢事务回滚而不是删除,因为它们会在事务开始之前将数据库保持在准确状态,但是如果你有数千个数据库,它可以显着降低测试速度。

    我有时质疑数据库测试的价值,并且支持在新数据库上运行集成测试的连续集成。这样我们就可以覆盖所有数据访问。 在单元测试中,我们只需使用Mockito或类似的模拟工具模拟数据访问层。