您现在的位置是:首页 > 正文

轻松模拟数据库

2024-02-01 06:46:20阅读 2

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

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

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

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

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

单元测试您的数据访问

当涉及数据库时,人们可能会很快跳到编写集成测试,因为他们要做的就是创建一个小的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

网站文章

  • Ubuntu20.04 安装 ROS2

    官方文档

    2024-02-01 06:46:13
  • 计算机断网后显示配置0%,电脑断网后自动报警提醒怎么设置

    很多小伙伴经常开着电脑在互联网上下载各种资料,大型软件、高清电影等等。但是这年头有些网络运营商经常各种不靠谱,带宽偷工减料不说,还时不时断网。于是经常出现这样一幕场景:1、打开电脑附件的命令提示符窗口...

    2024-02-01 06:46:06
  • 【Leetcode刷题】哈希

    【Leetcode刷题】哈希

    Leetcode1.两数之和、Leetcode290.单词规律、Leetcode594.最长和谐子序列、Leetcode17.电话号码的字母组合、Leetcode49.字母异位词分组、Leetcode...

    2024-02-01 06:45:36
  • chatgpt赋能Python-python_crc校验

    本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。对于颠覆工作方式的ChatGPT,应...

    2024-02-01 06:45:28
  • 修改docker_gwbridge的网段解决和内网ip冲突的问题

    修改docker_gwbridge的网段解决和内网ip冲突的问题

    1、要删除docker_gwbridge这个网络,但是一般是无法直接删除的,因为被很多容器使用,可以通过docker network inspect docker_gwbridge查看被哪些容器占用。...

    2024-02-01 06:45:20
  • mybatis pageHelpler分页不生效解决办法

    只配置当前这一个依赖 PageHelper不生效。<!-- mybatis pager --><dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version></dependency>还需要把这个依.

    2024-02-01 06:44:53
  • 两面翻转的盒子

    两面翻转的盒子

    html代码: 天官赐福 百无禁忌 一直都很喜欢这种花里胡哨的东西,这次先尝试了下文字,下次可以试试图片。 css代码:

    2024-02-01 06:44:47
  • java项目-第43期ssm项目前台+后台小说在线阅读系统

    项目简述 该项目是一款前后端交互的小说阅读系统,用户登录后可以查看各种小说章节。后台管理员进行小说维护 前台包含以下模块: 首页、最新上架图书、热门图书排行、个人中心 后台包含以下模块:个人信息模块、通用户管理、会员用户管理、支付记录管理、 会员余额查询、图书类别管理、图书信息管理、书评信息管理

    2024-02-01 06:44:41
  • 【机器学习模型详细推导5】-朴素贝叶斯分类

    朴素贝叶斯分类一. 朴素贝叶斯分类介绍二. 算法推导详解三. 附上《统计学习方法》中的算法流程一. 朴素贝叶斯分类介绍首先,对于更定数据集{(x1,y1),(x2,y2),…,(xm,ym)}\{ (...

    2024-02-01 06:44:36
  • 内置对象-Date对象(获取年月日-时分秒)

    内置对象-Date对象(获取年月日-时分秒)

    测试代码<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Com...

    2024-02-01 06:44:10