使用 JOOQ 的 MockDataProvider,如何设置返回的 lastId()?
Using the MockDataProvider of JOOQ, how do I set the lastId() that gets returned?
注意:我没有使用Jooq的代码生成器
在 DAO 单元测试中,测试 DAO 以确保在插入对象后,DAO 将 Id 设置为 return 由数据库中的 last_insert_id() 编辑。由于我使用的是 JOOQ 的 MockConnection 和 MockDataProvider,因此没有联系实际的数据库。
当 DAO 执行以下操作时:
DSLContext ctx = DSL.using(connection, SQLDialect.MYSQL);
//insert
//get id
BigInteger id = ctx.lastId();
JOOQ 执行以下查询:
select last_insert_id() from dual;
在我的 MockDataProvider 中,我检查何时执行此查询并 return 相应的结果:
import static org.jooq.impl.DSL.dual;
//other code
@Override
public MockResult[] execute(MockExecuteContext ctx) throws SQLException {
Field<BigInteger> id = DSL.field("", BigInteger.class);
Record record = dual().newRecord();
record.setValue(id, BigInteger.valueOf(1234567));
return new MockResult[] { new MockResult(record) };
}
当上面的 MockResult 被 returned 时,我得到以下异常
java.lang.IllegalArgumentException: Field () is not contained in Row ()
为 last_insert_id() 查询填充 MockResult 的正确方法是什么?
这是针对 DSLContext.lastID()
的 MockDataProvider
的有效实施:
BigInteger expected = BigInteger.valueOf(1234567);
DSLContext ctx = DSL.using(new MockConnection(c -> {
Field<BigInteger> id = DSL.field("last_insert_id()", BigInteger.class);
Record record = DSL.using(MYSQL).newRecord(id);
record.setValue(id, expected);
return new MockResult[] { new MockResult(record) };
}), SQLDialect.MYSQL);
assertEquals(expected, ctx.lastID());
您的方法基本上有两处错误:
字段名称
您选择的字段的字段名称实际上是 last_insert_id()
(至少在 jOOQ 3.5.3 中是这样),因此您也必须这样命名您的模拟字段:
Field<BigInteger> id = DSL.field("last_insert_id()", BigInteger.class);
记录
您必须创建一个已包含您的字段的记录。 dual()
table 包含不同的字段。 jOOQ 生成 from dual
查询的事实与您必须生成包含 last_insert_id()
字段的 Record
的事实无关:
Record record = DSL.using(MYSQL).newRecord(id);
警告
当然,您对 3.5.3 中的 jOOQ 实现做出了强有力的假设。无法保证 DSLContext.lastID()
生成的确切查询将始终是
select last_insert_id() from dual
注意:我没有使用Jooq的代码生成器
在 DAO 单元测试中,测试 DAO 以确保在插入对象后,DAO 将 Id 设置为 return 由数据库中的 last_insert_id() 编辑。由于我使用的是 JOOQ 的 MockConnection 和 MockDataProvider,因此没有联系实际的数据库。
当 DAO 执行以下操作时:
DSLContext ctx = DSL.using(connection, SQLDialect.MYSQL);
//insert
//get id
BigInteger id = ctx.lastId();
JOOQ 执行以下查询:
select last_insert_id() from dual;
在我的 MockDataProvider 中,我检查何时执行此查询并 return 相应的结果:
import static org.jooq.impl.DSL.dual;
//other code
@Override
public MockResult[] execute(MockExecuteContext ctx) throws SQLException {
Field<BigInteger> id = DSL.field("", BigInteger.class);
Record record = dual().newRecord();
record.setValue(id, BigInteger.valueOf(1234567));
return new MockResult[] { new MockResult(record) };
}
当上面的 MockResult 被 returned 时,我得到以下异常
java.lang.IllegalArgumentException: Field () is not contained in Row ()
为 last_insert_id() 查询填充 MockResult 的正确方法是什么?
这是针对 DSLContext.lastID()
的 MockDataProvider
的有效实施:
BigInteger expected = BigInteger.valueOf(1234567);
DSLContext ctx = DSL.using(new MockConnection(c -> {
Field<BigInteger> id = DSL.field("last_insert_id()", BigInteger.class);
Record record = DSL.using(MYSQL).newRecord(id);
record.setValue(id, expected);
return new MockResult[] { new MockResult(record) };
}), SQLDialect.MYSQL);
assertEquals(expected, ctx.lastID());
您的方法基本上有两处错误:
字段名称
您选择的字段的字段名称实际上是 last_insert_id()
(至少在 jOOQ 3.5.3 中是这样),因此您也必须这样命名您的模拟字段:
Field<BigInteger> id = DSL.field("last_insert_id()", BigInteger.class);
记录
您必须创建一个已包含您的字段的记录。 dual()
table 包含不同的字段。 jOOQ 生成 from dual
查询的事实与您必须生成包含 last_insert_id()
字段的 Record
的事实无关:
Record record = DSL.using(MYSQL).newRecord(id);
警告
当然,您对 3.5.3 中的 jOOQ 实现做出了强有力的假设。无法保证 DSLContext.lastID()
生成的确切查询将始终是
select last_insert_id() from dual