【问题标题】:Using the MockDataProvider of JOOQ, how do I set the lastId() that gets returned?使用 JOOQ 的 MockDataProvider,如何设置返回的 lastId()?
【发布时间】:2015-05-18 20:42:57
【问题描述】:

注意:我没有使用 Jooq 的代码生成器

在 DAO 单元测试中,测试 DAO 以确保在插入对象后,DAO 将 Id 设置为由数据库中的 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 中,我检查此查询何时执行并相应地返回结果:

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 时,我得到以下异常

java.lang.IllegalArgumentException: Field () is not contained in Row ()

为 last_insert_id() 查询填充 MockResult 的正确方法是什么?

【问题讨论】:

    标签: java unit-testing mocking jooq


    【解决方案1】:

    这是您的MockDataProvider 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());
    

    您的方法基本上有两件事出错:

    字段名称

    您选择的字段的字段名称实际上称为last_insert_id()(至少在 jOOQ 3.5.3 中),因此您还必须这样命名您的模拟字段:

        Field<BigInteger> id = DSL.field("last_insert_id()", BigInteger.class);
    

    记录

    您必须创建一个已包含您的字段的记录。 dual() 表包含不同的字段。 jOOQ 生成 from dual 查询的事实与您必须生成包含 last_insert_id() 字段的 Record 的事实无关:

        Record record = DSL.using(MYSQL).newRecord(id);
    

    警告

    当然,您对 jOOQ 在 3.5.3 中的实现做出了强有力的假设。无法保证DSLContext.lastID() 生成的确切查询始终是

    select last_insert_id() from dual
    

    【讨论】:

    • jOOQ 最棒的部分是,如果你提出一个关于 SO 的合理问题,jOOQ 的创建者总会给你一个答案;)
    • 你可能已经问过这个问题了。但是还有几十个人会用谷歌搜索它。有一个好的答案对很多人都很重要
    猜你喜欢
    • 2015-12-28
    • 2013-11-25
    • 2017-01-27
    • 2019-12-23
    • 1970-01-01
    • 2019-03-26
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多