可用版本: Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

模拟文件数据库

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

除了之前的编程方式实现模拟连接之外,另一种更声明式的方法是使用org.jooq.tools.jdbc.MockFileDatabase,它可以直接从文件中读取 SQL 语句及其对应的结果集。

免责声明:使用此 jOOQ API 模拟 JDBC 连接的一般思路是提供快速的解决方法、注入点等,使用一个非常简单的 JDBC 抽象。不建议使用此模拟 API 模拟整个数据库(包括复杂的转态转换、事务、锁定等)。一旦您有这种需求,请考虑使用实际的数据库产品进行集成测试,而不是在 MockDataProvider 内部实现您的测试数据库。

假设以下文件内容

# All lines with a leading hash are ignored. This is the MockFileDatabase comment syntax
-- SQL comments are parsed and passed to the SQL statement
/* The same is true for multi-line SQL comments */
select 'A';
> A
> -
> A
@ rows: 1

select 'A', 'B' union all 'C', 'D';
> A B
> - -
> A B
> C D
@ rows: 2

# Statements without result sets just leave that section empty
update t set x = 1;
@ rows: 3

# Statements producing specific exceptions can indicate them as such
select * from t;
@ exception: ACCESS TO TABLE T FORBIDDEN

以上语法包含以下元素来定义单个语句

  • MockFileDatabase 注释是任何以井号 ("#") 开头的行。读取文件时将忽略它们
  • SQL 注释是 SQL 语句的一部分
  • SQL 语句始终在新行开始,并以分号 (;) 结尾,这是行上的最后一个符号(除了空白字符)
  • 如果语句有结果集,它会立即紧随 SQL 语句,并以尖括号和空格 ("> ") 为前缀。接受 DSLContext.fetchFromTXT()DSLContext.fetchFromJSON()DSLContext.fetchFromXML() 接受的任何格式。
  • 语句始终以行数结尾,该行数以 at 符号、“rows”关键字和双冒号 ("@ rows:") 为前缀。

上面的数据库总共支持两个语句,并且是完全无状态的(例如,不能使 INSERT 语句影响同一表上的后续 SELECT 语句的结果)。可以通过以下方式加载 MockFileDatabase

// Initialise your data provider:
MockFileDatabase provider = new MockFileDatabase(new File("/path/to/db.txt"));
MockConnection connection = new MockConnection(provider);

// Pass the mock connection to a jOOQ DSLContext:
DSLContext create = DSL.using(connection, SQLDialect.POSTGRES);

// Execute queries transparently, with the above DSLContext:
Result<?> result = create.select(inline("A")).fetch();
Result<?> result = create.select(inline("A"), inline("B")).fetch();

// Queries that are not listed in the MockFileDatabase will simply fail
Result<?> result = create.select(inline("C")).fetch();

在预期查询集定义良好的情况下,MockFileDatabase 可以提供一种非常有效的方法来模拟数据库引擎的某些部分,而无需提供编程模拟连接的完整功能。

使用正则表达式匹配语句

或者,可以使用正则表达式按照文件中定义的顺序匹配语句。

# Regardless of the number of columns, if selecting 'A' as the first column,
# always return a single row containing columns A and B
select 'A', .*;
> A B
> - -
> A B
@ rows: 1

# All other select statements are assumed to return only a column A
select .*;
> A
> -
> A
@ rows: 1

与之前相同的规则适用。第一个匹配的语句将应用于任何给定的输入语句。

此功能是“可选加入”的,因此必须进行适当的配置

// Initialise your data provider:
MockFileDatabase provider = new MockFileDatabase(new MockFileDatabaseConfiguration()
    .source(new File("/path/to/db.txt"))
    .patterns(true) // Turn on regular expressions here
);
MockConnection connection = new MockConnection(provider);

// Pass the mock connection to a jOOQ DSLContext:
DSLContext create = DSL.using(connection, SQLDialect.POSTGRES);

// This returns a column A only
Result<?> result = create.select(inline("X")).fetch();

// This returns columns A and B
Result<?> result = create.select(inline("A"), inline("B"), inline("C")).fetch();

反馈

您对此页面有任何反馈吗? 我们很乐意倾听!

The jOOQ Logo