Ald*_*ian 5 java unit-testing jdbc h2
我经常遇到同样的问题:我想使用内存数据库对我的 DAO 执行单元测试。我正在使用 H2,但我相信问题与 HSQLDB 几乎相同。我的单元测试涉及三个步骤:
在非常简单的情况下,可以对所有三个步骤使用完全相同的连接,但是一旦事情变得稍微复杂一点(例如,当使用查询数据库的框架而不是使用直接的PreparedStatements时),每个步骤一个连接需要执行步骤。
问题:一旦连接关闭,数据库似乎就会被删除。怎么解决呢?
关于这个主题,H2文档给出了两个提示:
有时需要与同一个内存数据库的多个连接。在这种情况下,数据库 URL 必须包含名称。例子:
jdbc:h2:mem:db1。使用此 URL 访问同一数据库只能在同一虚拟机和类加载器环境中进行。默认情况下,关闭最后一个数据库连接将关闭数据库。对于内存数据库来说,这意味着内容丢失。要保持数据库打开,请添加
;DB_CLOSE_DELAY=-1到数据库 URL。要在虚拟机处于活动状态时保留内存数据库的内容,请使用jdbc:h2:mem:test;DB_CLOSE_DELAY=-1.
所以第一个解决方案是添加;DB_CLOSE_DELAY=-1到 h2 url。但我对此有点不满意,因为它说数据库将永远保留在内存中,而我希望它只在我的测试运行时存在。
有关DB_CLOSE_DELAY 的文档提供了更多信息:
设置所有连接都关闭时关闭数据库的延迟。值 -1 表示数据库永远不会关闭,直到关闭延迟设置为其他值或被
SHUTDOWN调用。值 0 表示无延迟(默认值;如果数据库的最后一个连接关闭,则数据库将关闭)。值 1 及更大值表示关闭最后一个连接后数据库保持打开状态的秒数。
它暗示了其他解决方案,例如在关闭或手动调用之前给予一点延迟SHUTDOWN(我还没有找到如何在内存数据库上使用)。
最后,这是我的解决方法:由于数据库在最后一个连接关闭时关闭,因此从创建数据库时直到我不再需要它时,我将保持打开一个空白连接。这个解决方法有点hacky(只为了保持数据库的活动而打开备用连接基本上是一种浪费),但它是迄今为止我发现的最优雅的解决方案。这是抽象单元测试类的一个非常简化的片段,说明了该解决方案:
import org.h2.jdbcx.JdbcDataSource;
public abstract class AbstractTestDao {
private Connection blankConnection;
private DataSource dataSource;
protected DataSource getDataSource() {
return dataSource;
}
@Before
public void setup() throws SQLException {
JdbcDataSource jdbcDataSource = new JdbcDataSource();
jdbcDataSource.setUrl("jdbc:h2:mem:test");
this.dataSource = jdbcDataSource;
this.blankConnection = dataSource.getConnection();
}
@After
public void tearDown() throws SQLException {
this.blankConnection.close();
}
}
Run Code Online (Sandbox Code Playgroud)
子单元测试类将继承这个类,并使用提供的 DataSource 对象来初始化用于查询数据库的库,以及执行问题中列出的其他两个步骤。测试完成后,空白连接将关闭,内存数据库也将关闭。
| 归档时间: |
|
| 查看次数: |
4389 次 |
| 最近记录: |