【问题标题】:Some clarifications about using H2 with junit?关于将 H2 与 junit 一起使用的一些说明?
【发布时间】:2017-09-08 06:55:05
【问题描述】:

下面给了我:

org.h2.jdbc.JdbcSQLException:表“FOO”已经存在; SQL 声明

这让我感到困惑并希望得到一些澄清。

H2 服务器何时启动/关闭,getConnectionclose

为什么会出现already exists?当 H2 服务器启动时,架构是否从以前的会话中持久化?

关于在 H2 中设置测试模式和数据集以用于数据库单元测试的任何最佳实践建议?

public class MyTest {
    @Before
        public void setUp() throws ClassNotFoundException, SQLException {
            try {
                   Class.forName("org.h2.Driver");
                    Connection conn = DriverManager.getConnection("jdbc:h2:~/test;MODE=Oracle", "sa", "");
                    // add application code here


                    Statement statement =conn.createStatement();
                    statement.execute("create table foo (id integer)");
                    conn.commit();

                    ResultSet rs = statement.executeQuery("select * from foo");
                    if (rs.next()) {
                            System.out.println(rs.getString("id"));
                    }

                    statement.execute("insert into foo (id) values (5)");
                    conn.commit();

                    rs = statement.executeQuery("select * from foo");
                    if (rs.next()) {
                            System.out.println(rs.getString("id"));
                    }


                    conn.close();
            } catch (Throwable t) {
                t.printStackTrace();
            }

        }


    @Test
    public void test() {

    }
}

【问题讨论】:

  • 您没有足够的代码示例来确定如何创建/销毁您的 H2 数据库。至少应该在所有单元测试运行之前和之后创建和销毁数据库。您出现“表已存在”错误的可能原因是您在每个单元测试之前创建表,如果您有多个单元测试并且 H2 尚未被销毁(很可能不会),您最终将创建相同的针对同一个 H2 实例多次表。尝试将@Before 更改为@BeforeClass 并将setUp 设置为静态,看看您是否会遇到同样的问题。
  • @tsolakp 我排除的唯一代码是一个空测试方法,我已更新问题以包含此代码。使用 @BeforeClass 的静态设置方法不会产生任何变化。我非常不清楚数据库是如何创建/销毁的,它是由getConnection 调用创建的吗?
  • H2 数据库不是由getConnection 创建的,它会在 JVM 启动时创建,以便运行您的单元测试。

标签: java


【解决方案1】:

问题就在这里:

DriverManager.getConnection("jdbc:h2:~/test;MODE=Oracle", "sa", "");

您的连接字符串告诉 H2 使用文件系统作为存储,位于 $HOME/test 下,因此它在测试中持续存在也就不足为奇了。

来自doc

嵌入式:
- jdbc:h2:~/test: 用户主目录中的“测试”
- jdbc:h2:/data/test: 'test' 在目录/data

内存中:
- jdbc:h2:mem:test 一个进程中的多个连接
- jdbc:h2:mem: 未命名的私人;一个连接

还有一个服务器模式,但你没有使用它,而且它对单元测试毫无意义。对于单元测试,根据您的测试设计,您可能需要两种内存模式中的一种。

【讨论】:

    【解决方案2】:

    H2 是内存数据库。但它实际上在某些文件中缓存了数据。你可以在你的项目中找到它们。

    您可以使用DBUnit

    希望对你有帮助

    【讨论】:

    猜你喜欢
    • 2019-05-14
    • 2011-02-04
    • 1970-01-01
    • 2015-06-22
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多