模拟文件数据库
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
除了之前的编程方式实现模拟连接之外,另一种更声明式的方法是使用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();
反馈
您对此页面有任何反馈吗? 我们很乐意倾听!