JUnit:测试DAO – 回滚或删除

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

谢谢!

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

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

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

交易有两个原因:

  • 写入/删除可能比回滚更昂贵
  • 误差范围较小(您删除数据的代码可能有错误)

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

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

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

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

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

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

  1. 代码似乎超过了测试。 我们找到了一个代码库,其中在内存中测试的表在实际数据库中不存在。
  2. 数据库并不完全相同,如果你在内存中使用hsql,但你的主数据库是MySQL,那么语法,日期等等都会有所不同。 我知道你可以使用ASCII Sql,但是你正在测试一些不是你要运行的东西。 会有分歧。

我更喜欢事务回滚而不是删除,因为它们在事务开始之前将数据库保持在准确状态,但如果你有数千个数据库,它可以显着降低测试速度。

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