如何使用 H2-in-memory 数据库测试 JDBI DAO?

Posted

技术标签:

【中文标题】如何使用 H2-in-memory 数据库测试 JDBI DAO?【英文标题】:How to test JDBI DAO's with H2-in-memory database? 【发布时间】:2016-06-19 22:04:21 【问题描述】:

我将 Dropwizard 框架与 JDBI 和 h2-in-memory 一起用于我的测试目的。我也写了我的 DAO,现在我想用单元测试来测试它们。我来到了似乎符合我要求的 DBUnit。

但是如何将它与 JDBI 集成并填充测试数据呢?

【问题讨论】:

【参考方案1】:

我是这样实现的:

我创建了一个基础 dao 类,用于设置我的 DW 环境来为我构建一个 DBI 实例。看起来像这样:

@BeforeClass
    public static void setup() 
        env = new Environment( "test-env", Jackson.newObjectMapper(), null, new MetricRegistry(), null );
        dbi = new DBIFactory().build( env, getDataSourceFactory(), "test" );
        dbi.registerArgumentFactory(new JodaDateTimeArgumentFactory());
        dbi.registerMapper(new JodaDateTimeMapper(Optional.absent()));
    

    static DataSourceFactory getDataSourceFactory()
    
        DataSourceFactory dataSourceFactory = new DataSourceFactory();
        dataSourceFactory.setDriverClass( "org.h2.Driver" );
        dataSourceFactory.setUrl( "jdbc:h2:mem:testDb" );
        dataSourceFactory.setUser( "sa" );
        dataSourceFactory.setPassword( "" );
        return dataSourceFactory;
    

    public static DBI getDbi() 
        return dbi;
    

    public static Environment getEnvironment() 
        return env;
    

这不会为您创建指向内存数据库的数据源。

在实际测试中不可以在测试前使用 DBI 实例创建 DAO:

DaoA dao;
DaoB otherDao;

@Before
public void setupTests() throws IOException 
    super.setupTests();
    dao = dbi.onDemand(DaoA.class);
    otherDao = dbi.onDemand(DaoB.class);

这样您就可以开始测试了。希望对您有所帮助。

阿图尔

为初始化编辑:

我的测试也会自行初始化。为此,我直接使用 dbi 来执行 sql 脚本。例如,测试与作为测试类路径资源的 test1.sql 脚本相关联。在这种情况下,我需要做的就是阅读该脚本并在测试之前运行它。比如这样:

            StringWriter writer = new StringWriter();
            InputStream resourceStream = this.getClass().getResourceAsStream("/sql/schema.sql");
            if(resourceStream == null ) 
                throw new FileNotFoundException("schema not found");
            
            IOUtils.copy(resourceStream, writer);
            Handle handle = null;
            try 
                handle = dbi.open();
                handle.execute(writer.toString());
                handle.commit();
             finally 
                handle.close();
                if(resourceStream != null) 
                    resourceStream.close();
                
                writer.close();
            

【讨论】:

好的,谢谢!这就是我一直在寻找的。但出于测试目的,我想用我的测试数据填充我的测试数据库(以测试 GET 方法),我的目标是让我的测试彼此独立。除了手动查询 jdbi 数据库之外,有没有一种优雅的方法可以用模型类填充我的数据库? 您的代码不起作用。 IOUtils.copy(resourceStream, writer); - 这是不正确的super.setupTests(); - 你在扩展哪个类? 我的代码不是我的生产代码的完整副本。 IOUtils 是 apache-commons-io。他们所做的只是复制一个输入流。 super.setupTests() 调用使用 IOUtils 调用部件。正如方法所建议的那样,它设置了我的测试。因此它将运行初始化脚本,初始化 DBI,然后返回创建该 DBI 实例的 DAO。 在 dbi org.apache.tomcat.jdbc.pool.ConnectionPool init 上打开句柄时出现错误严重:无法创建池的初始连接。 org.h2.jdbc.JdbcSQLException:找不到数据库“mem:test”[90013-193] 嗨,我需要更多关于 thtat 的信息。我相信上述解决方案适用于相当旧的 DW 版本(可能是 0.8),而最新版本的依赖项有大量更新。

以上是关于如何使用 H2-in-memory 数据库测试 JDBI DAO?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security JWT - 400 错误请求:“无效授权”“错误凭据”

javafx如何测试图像相等性?

如何使用 reduce 测试 Math.max 函数的数组

用于失败测试用例的 J Meter 电子邮件配置

使用poi如何设置指定单元格的颜色

与 MySql 的连接正在自动中止。如何正确配置Connector/J?