问题描述
注意:我没有使用Jooq的代码生成器
在DAO单元测试中,对DAO进行测试以确保在插入对象之后,DAO设置了last_insert_id()从数据库返回的ID.自从我使用JOOQ的MockConnection和MockDataProvider以来,没有任何实际的数据库被联系.
In the DAO unit test, the DAO is tested to ensure that after a object has been inserted that the DAO sets the Id as returned by the last_insert_id() from the database. No actual database is contacted since I'm using the MockConnection and MockDataProvider of JOOQ.
当DAO执行以下操作时:
When the following is executed by the DAO:
DSLContext ctx = DSL.using(connection, SQLDialect.MYSQL);
//insert
//get id
BigInteger id = ctx.lastId();
JOOQ执行以下查询:
JOOQ executes the following query:
select last_insert_id() from dual;
在我的MockDataProvider中,我检查何时执行此查询并相应地返回结果:
In my MockDataProvider I check when this query is executed and return a result accordingly:
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时,出现以下异常
When the above MockResult is returned, I get the following exception
java.lang.IllegalArgumentException: Field () is not contained in Row ()
为last_insert_id()查询填充MockResult的正确方法是什么?
What is the correct way to populate the MockResult for the last_insert_id() query ?
推荐答案
这是针对DSLContext.lastID()
的MockDataProvider
的有效实现:
This is a working implementation for your MockDataProvider
for DSLContext.lastID()
:
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());
您的方法本质上有两件事出错了:
There are essentially two things that went wrong in your approach:
您选择的字段的字段名称实际上称为last_insert_id()
(至少在jOOQ 3.5.3中),因此,您还必须以这种方式命名模拟字段:
The field name of the field you're selecting is really called last_insert_id()
(at least in jOOQ 3.5.3), thus you also have to name your mock field this way:
Field<BigInteger> id = DSL.field("last_insert_id()", BigInteger.class);
记录
您必须创建一条记录,其中已包含您的字段. dual()
表包含一个不同的字段. jOOQ生成from dual
查询的事实与必须生成包含last_insert_id()
字段的Record
的事实无关.
The Record
You have to create a record that already contains your field in it. The dual()
table contains a different field. The fact that jOOQ generates a from dual
query is irrelevant to the fact that you have to produce a Record
that contains a last_insert_id()
field:
Record record = DSL.using(MYSQL).newRecord(id);
警告
当然,您对jOOQ的实现(如3.5.3中的假设)有一个很强的假设.无法保证DSLContext.lastID()
生成的确切查询将始终为
Warning
Of course, you're making a strong assumption about jOOQ's implementation as it is in 3.5.3. There is no guarantee that the exact query generated by DSLContext.lastID()
will always be
select last_insert_id() from dual
这篇关于使用JOOQ的MockDataProvider,如何设置要返回的lastId()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!