清空整个数据库(用于使用Hibernate进行单元测试)

8

我的单元测试使用Hibernate连接到一个内存中的HSQLDB数据库。我希望有一种方法可以在JUnit的TestCase.setUp()方法中清除并重新创建数据库(包括架构和所有数据)。


3
如果你正在测试你的数据库,那么在我看来这不是单元测试。 - Jamie
我正在测试我的程序,它恰好使用了数据库。 - Jack Edmonds
我正在测试一个用于访问数据库中数据的类。 - Ilya Serbis
5个回答

7

您可以配置Hibernate配置文件,以便每次强制数据库重新创建您的表和模式。

<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create-drop</property>

hibernate.hbm2ddl.auto:在创建SessionFactory时,自动验证或将模式DDL导出到数据库。使用create-drop选项,当显式关闭SessionFactory时,将删除数据库模式。

例如:validate | update | create | create-drop

如果您不想在实际的Hibernate配置中使用此配置,则可以为单元测试目的创建一个Hibernate配置。


7
每次运行都会重新创建它,这意味着如果你从 Eclipse 运行测试,许多本来可以通过的测试将失败。至少这是我的经验。 - Bill K
1
@BillK 这也是我的经验。 - Craig Otis

4

2
hibernate.hbm2ddl.auto=create-drop

并引导一个新的SessionFactory


1

从测试角度来看,最佳实践是在每个单独的测试后清除数据。如果您使用create-drop,则还会删除表模式。这会导致每次重新创建模式的开销。

由于您正在使用提供直接截断机制的hsql,在这种情况下,它将是最佳选择。


@After
public void clearDataFromDatabase() {
    //Start transaction, based on your transaction manager
    dao.executeNativeQuery("TRUNCATE SCHEMA PUBLIC AND COMMIT"); 
    //Commit transaction
}   

0

小心每次清除世界并重新开始。很快,您可能希望在系统中加载“默认”测试数据。因此,您真正想要的是在每次测试运行之前恢复到该基本状态。在这种情况下,您需要一个回滚事务

为了实现这一点,您应该注释您的JUnit类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:/path/to/spring-config.xml"})
@TransactionConfiguration(transactionManager="myTransactionManager", defaultRollback=true)
public class MyUnitTestClass {
...
}

然后使用@Transactional标注您的每个测试方法:

@Transactional
@Test
public void myTest() {
    ...
}

无论作者是否愿意,所提出的方法都会缩小可以进行此类测试的场景范围,例如您无法在并行事务中进行多线程测试并在最后回滚。 - okutane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接