【问题标题】:How can I wipe data from my HSQLDB after every test?每次测试后如何从 HSQLDB 中擦除数据?
【发布时间】:2011-06-26 19:11:39
【问题描述】:

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

【问题讨论】:

    标签: java hibernate junit hsqldb


    【解决方案1】:
    1. 您可以通过删除架构来清除数据。默认模式称为 PUBLIC。如果执行下面的 SQL 语句,它将清除所有数据并删除所有表。

      DROP SCHEMA 公共级联

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

      files_read_only=true

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

      TRUNCATE SCHEMA 公开并提交

      此语句在最新版本的 HSQLDB 中得到了增强。请参阅 Truncate Statement

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

    【讨论】:

    • 这将删除架构中的所有表。但是,我的要求是我需要表格但其中没有数据
    • #3 非常适合我。由于各种原因我无法在测试方法之间回滚,所以我做了一个@@After @@Transactional 方法,它接受实体管理器并执行它。
    【解决方案2】:

    按照 fredt 的建议,截断 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 对象被重置为其起始值

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 如果您只测试单个事务,这是一个好主意。测试可能包含多个事务。
      【解决方案4】:

      另一个解决方案列在“清除测试之间的数据库”http://www.objectpartners.com/2010/11/09/unit-testing-your-persistence-tier-code/

      【讨论】:

        【解决方案5】:

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

        TRUNCATE SCHEMA public AND COMMIT;
        

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

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

        【讨论】:

        • entityManager 来自哪里?
        • 当我在项目中使用 JPA 和 Spring for DI 时,它是由测试运行程序为我注入的。
        猜你喜欢
        • 2018-05-23
        • 2015-09-07
        • 1970-01-01
        • 2019-01-01
        • 1970-01-01
        • 2011-06-10
        • 2021-02-01
        • 1970-01-01
        • 2019-11-26
        相关资源
        最近更新 更多