轻松模拟数据库

本文介绍了如何在数据库单元测试中避免使用真实数据库,重点在于利用jOOQ的MockConnection特性来模拟数据访问。通过实现MockDataProvider接口,可以定制SQL执行的响应,从而在测试中精确控制数据行为。此外,文章还提到了MockFileDatabase的实验性实现,为单元测试提供文本格式的模拟数据。jOOQ的模拟功能甚至可以扩展到其他数据库查询框架,使其成为强大的JDBC模拟工具。
摘要由CSDN通过智能技术生成

测试驱动的开发真是太好了! 在组织中建立它之后,您将开始:

  • 极大地提高您的质量(事情不常发生)
  • 大大改善您的流程(事情可以更轻松地更改)
  • 极大地改善您的开发人员氛围(事情更有趣)

进行正确的测试驱动开发的重要性是找到要覆盖的代码的良好比例。

  • 通过自动单元测试
  • 通过自动集成测试
  • 通过手动“烟雾测试”
  • 通过手动的“验收测试”
  • 一点也不

找到该比例可以作为激烈的宗教讨论的依据。 我很快将在博客中发表关于该主题的个人看法。 但是,在本文中,我们将重点介绍第一种测试: 单元测试

单元测试您的数据访问

当涉及数据库时,人们可能会很快跳到编写集成测试,因为他们要做的就是创建一个小的Derby,H2或HSQLDB(或其他)测试数据库,并在实际运行之前运行几个数据设置查询。测试。 希望他们的代码模块不会注意到对生产环境的影响,并且整个系统可以作为黑箱进行测试。 这样做的好处是可以以验证您的业务需求,用户案例或任何您称呼的方式编写测试。 到目前为止,理论。

当这些数据库集成测试堆积如山时,将它们相互隔离变得越来越困难。 避免相互依赖,同时避免昂贵的数据库设置非常困难。 构建/提交后,您将无法立即运行整个测试套件。 您需要每晚构建,每周构建。 但是对数据访问层进行单元测试并没有那么容易! 因为JDBC是一个可怕的API,所以很难模仿。 通过这种高度状态化的API配置和执行查询的方法有很多,您的单元测试很快就变得难以管理。

有一些库可以帮助您进行数据库测试。 仅举几个:

  • MockRunner :这具有一些特定于JDBC的扩展,这些扩展允许模拟JDBC结果集以及检查是否执行了实际查询
  • jMock :一个“普通” Java模拟库
  • mockito :一个“普通的” Java模拟库
  • DBUnit :这不会模拟您的数据库,对测试数据库很有用。 另一个用例,但仍然值得一提

上述某些库无法解决JDBC是一个难以模仿的API的事实,特别是如果您需要同时支持多个(不兼容!)版本的JDBC时。 一些示例可以在这里看到:

用jOOQ模拟数据库

在应用程序中使用jOOQ时,在jOOQ 3.0中对数据库进行模拟变得非常容易。 jOOQ现在还提供了Mock JDBC Connection 。 但是,与其他框架不同,您只需要使用jOOQ实现单个功能接口,并将该实现提供给MockConnection: MockDataProvider 。 这是一个简单的实现示例:

MockDataProvider provider = new MockDataProvider() {

    // Your contract is to return execution results, given a context
    // object, which contains SQL statement(s), bind values, and some
    // other context values
    @Override
    public MockResult[] execute(MockExecuteContext context) 
    throws SQLException {

        // Use ordinary jOOQ API to create an org.jooq.Result object.
        // You can also use ordinary jOOQ API to load CSV files or
        // other formats, here!
        Result<MyTableRecord> result = executor.newResult(MY_TABLE);
        result.add(executor.newRecord(MY_TABLE));

        // Now, return 1-many results, depending on whether this is
        // a batch/multi-result context
        return new MockResult[] {
            new MockResult(1, result)
        };
    }
};

// Put your provider into a MockConnection and use that connection
// in your application. In this case, with a jOOQ Executor:
Connection connection = new MockConnection(provider);
Executor create = new Executor(connection, dialect);

// Done! just use regular jOOQ API. It will return the values
// that you've specified in your MockDataProvider
assertEquals(1, create.selectOne().fetch().size());

上面的实现充当JDBC的各种executeXXX()方法的回调。 通过非常简单的MockExecuteContext API ,您可以:

  • 获取对已执行的SQL的访问并绑定值(使用通用jOOQ API将绑定值内联到SQL语句中)
  • 区分常规SQL语句与单语句/多绑定值和多语句/无绑定值批处理
  • 使用jOOQ的org.jooq.Result对象返回一个或几个结果(您可以轻松地从CSV,XML,JSON,TEXT格式导入)
  • 通过相同的API返回“生成的密钥”结果
  • 让jOOQ的MockStatement负责通过JDBC API对模拟数据进行序列化

还有一个MockFileDatabase的实验性实现, MockFileDatabase是使用以下格式的基于文本的模拟数据库:

# This is a sample test database for MockFileDatabase
# Its syntax is inspired from H2's test script files

# When this query is executed...
select 'A' from dual;
# ... then, return the following result
> A
> -
> A
@ rows: 1

# Just list all possible query / result combinations
select 'A', 'B' from dual;
> A B
> - -
> A B
@ rows: 1

select 'TABLE1'.'ID1', 'TABLE1'.'NAME1' from 'TABLE1';
> ID1 NAME1
> --- -----
> 1   X
> 2   Y
@ rows: 2

MockFileDatabase实现了MockDataProvider,因此为单元测试提供示例数据非常简单。 jOOQ的未来版本将允许:

  • 正则表达式模式匹配的SQL语句以提供模拟结果
  • 从其他格式加载这些结果,例如jOOQ支持的导出格式
  • 指定批处理语句,多结果语句等的行为。

在其他上下文中使用jOOQ的MockConnection

事情不止于此。 由于jOOQ的MockConnection是jOOQ的此模拟子API的入口,因此您也可以在其他环境中使用它,例如在运行JPA查询,Hibernate查询,iBatis或仅使用普通的旧式JDBC查询时。

jOOQ刚刚成为您首选的JDBC模拟框架!

参考:JAVA,SQL和JOOQ博客上我们的JCG合作伙伴 Lukas Eder 轻松模拟了您的数据库

翻译自: https://www.javacodegeeks.com/2013/02/easy-mocking-of-your-database.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值