在测试数据库操作时将数据库重置为已知状态的最佳方法是什么?

soc*_*soc 7 java database testing junit

我正在使用 JUnit 为在测试数据库上运行的某些方法编写测试。

我需要在每个@Test. 我想知道什么是最好的方法来做到这一点。

里面有什么方法EntityManager吗?还是我应该手动或使用 SQL 语句删除所有内容?删除并重新创建整个数据库会更好吗?

Mat*_*ell 5

我过去使用的一种技术是通过简单地从标准“测试数据库”复制数据库并在测试中使用它来从头开始重新创建数据库。

此技术适用于:

  1. 您的架构变化不大(否则很难保持一致)
  2. 您正在使用类似 hibernate 的东西,它与数据库无关。

这具有以下优点:

  1. 它与管理自己事务的代码一起工作。我的集成测试在 junit 下运行。例如,当我测试批处理时,我从 junit 调用 Batch.main() 并在前后测试内容。我不想更改被测代码中的事务处理。
  2. 它相当快。如果文件足够小,那么速度不是问题。
  3. 它使在 ci 服务器上运行集成测试变得容易。数据库文件与代码一起检入。无需启动和运行真正的数据库。

以及以下缺点:

  1. 测试数据库文件需要与真实数据库一起维护。如果您一直在添加列,这可能会很痛苦。
  2. 有管理 jdbc url 的代码,因为它们在每次测试时都会发生变化。

我将它与 Oracle 作为生产/集成数据库和 hsqldb 作为测试数据库一起使用。它工作得很好。hsqldb 是单个文件,因此很容易复制。

因此,在@Before 中,使用hsqldb,将文件复制到诸如target/it/database/name_of_test.script 之类的位置。这是在测试中得到的。

@After 中,您删除文件(或只是保留它,谁在乎)。使用 hsqldb,您还需要执行 SHUTDOWN,以便您可以删除该文件。

您还可以使用从ExternalResource扩展的@Rule,这是管理资源的更好方法。

另一个提示是,如果您使用 maven 或类似的东西,您可以在 target 中创建数据库。我使用目标/它。这样,当我执行和 mvn clean 时,数据库的副本会被删除。对于我的批次,我实际上也将所有其他属性文件等复制到此目录中,因此我也没有在奇怪的地方出现任何文件。