每次测试后如何从HSQLDB中擦除数据?

时间:2011-02-14 09:11:28

标签: java hibernate junit hsqldb

我的项目中已经编写了一些JUnit测试,用于在setup方法中填充数据。现在我已将maven添加到我的项目中,我想从maven执行所有测试用例,即使用mvn test。现在的问题是我的数据库在每个测试类运行后都没有被清除。我需要在每个类的测试用例运行后清除HSQLDB。

5 个答案:

答案 0 :(得分:79)

  1. 您可以通过删除架构来清除数据。默认架构称为PUBLIC。如果您执行下面的SQL声明,它将清除所有数据并删除所有表。

    DROP SCHEMA PUBLIC CASCADE

  2. 或者,如果需要表和模式对象定义,则可以创建一个文件:包含对象但没有数据的数据库,并将下面的属性添加到.properties文件中。使用此类型的数据库进行测试,不会保留对数据的更改

    files_read_only = true

  3. HSQLDB 2.2.6及更高版本中提供的最新替代方案允许您在保留表的同时清除模式中的所有数据。在下面的示例中,将清除PUBLIC架构。

    TRUNCATE SCHEMA public AND COMMIT

    此语句已在最新版本的HSQLDB中得到增强。请参阅截断声明

  4. 下的http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_truncate_statement

答案 1 :(得分:19)

按照fredt的建议, TRUNCATE SCHEMA PUBLIC RESTART IDENTITY并且不提交检查 为我工作。 DAO的JUnit测试中相关的代码部分。

@After
public void tearDown() {
    try {
        clearDatabase();
    } catch (Exception e) {
        fail(e.getMessage());
    }
}


public void clearDatabase() throws Exception {
  DataSource ds = (DataSource) SpringApplicationContext.getBean("mydataSource");
  Connection connection = null;
  try {
    connection = ds.getConnection();
    try {
      Statement stmt = connection.createStatement();
      try {
        stmt.execute("TRUNCATE SCHEMA PUBLIC RESTART IDENTITY AND COMMIT NO CHECK");
        connection.commit();
      } finally {
        stmt.close();
      }
    } catch (SQLException e) {
        connection.rollback();
        throw new Exception(e);
    }
    } catch (SQLException e) {
        throw new Exception(e);
    } finally {
        if (connection != null) {
            connection.close();
        }
    }
}

根据文件 http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_truncate_statement

  

如果指定了RESTART IDENTITY,则表示所有表IDENTITY序列和所有表   架构中的SEQUENCE对象将重置为其起始值

答案 2 :(得分:9)

我们在所有测试中所做的是在执行结束时(在所有断言完成后)回滚事务。我们使用Spring,并且默认情况下的测试不会在最后提交。这可确保您始终返回到数据库的起始状态(在初始创建实体表和运行import.sql之后)。

即使您不使用Spring,也可以使用自己的try {} finally {}块来回滚每个测试的已启动事务。

答案 3 :(得分:3)

“在测试之间清除数据库”http://www.objectpartners.com/2010/11/09/unit-testing-your-persistence-tier-code/

中列出了另一种解决方案

答案 4 :(得分:2)

我有一个简单的SQL脚本在每次测试之前运行,并在开头使用以下语句:

TRUNCATE SCHEMA public AND COMMIT;

但我在测试之间遇到了锁定问题,并且添加这对我来说就像一个魅力:

@After
public void after() throws Exception {
    if (entityManager.getTransaction().isActive()) {
        entityManager.getTransaction().rollback();
    }
}