Jooq query mock

273 views
Skip to first unread message

Hagi Cohen

unread,
Sep 14, 2021, 1:17:16 AM9/14/21
to jOOQ User Group
I work with Jooq on our system and I try mock DB (MYSQL) for testing.

I using JDBC mocking for unit test  from your guide https://www.jooq.org/doc/3.7/manual/tools/jdbc-mocking/

I didn’t understand and didn’t success get result for query as example:
I add more records to results  but when run this query I get all results and look filter (where) not execute.
Result<BookRecord> result = create.selectFrom(BOOK).where(BOOK.ID.eq(5)).fetch();

Can you please help me how write the mock correctly so I get in the end results of query and not all records created.

Message has been deleted

Lukas Eder

unread,
Sep 14, 2021, 3:19:35 AM9/14/21
to jOOQ User Group
Hi Hagi,

The manual already shows how to do it "correctly", but maybe, you can show exactly what you did? Otherwise, it will be difficult to spot what you might have done wrong.

Thanks
Lukas

--
You received this message because you are subscribed to the Google Groups "jOOQ User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jooq-user+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jooq-user/200930b2-d95c-4df5-90aa-0b7d3c179bb9n%40googlegroups.com.

Hagi Cohen

unread,
Sep 14, 2021, 3:29:56 AM9/14/21
to jOOQ User Group
Of course 

public class MyDataProvider : MockDataProvider {


@Throws(SQLException::class)
override fun execute(ctx: MockExecuteContext): Array<out MockResult>? {
val create = using(SQLDialect.MYSQL)

val sql = ctx.sql()
println(sql)

val result = create.newResult<Int, String>(field(AUTHOR.ID), field(AUTHOR.LAST_NAME))
result.add(create.newRecord(field(AUTHOR.ID), field(AUTHOR.LAST_NAME)).values(1, "Orwell"))
result.add(create.newRecord(field(AUTHOR.ID), field(AUTHOR.LAST_NAME)).values(2, "One"))
var mock = MockResult(1, result)

return arrayOf(mock)
}

}




@Test
fun JooqTest() {
val provider = MyDataProvider()
val connection = MockConnection(provider)
val create = DSL.using(connection, SQLDialect.DEFAULT)
var rq = create.select().from(AUTHOR.TABLE).where(AUTHOR.ID.eq(2)).fetch()
}

when I run it I get on rq :
0 = {RecordImpl@6450} "+----+---------+\n|  id|LAST_NAME|\n+----+---------+\n|   1|Orwell   |\n+----+---------+\n"
1 = {RecordImpl@6451} "+----+---------+\n|  id|LAST_NAME|\n+----+---------+\n|   2|One      |\n+----+---------+\n"

I expected get only second row


Br,
Hagi

Lukas Eder

unread,
Sep 14, 2021, 3:35:17 AM9/14/21
to jOOQ User Group
Hi Hagi,

But why would you expect only the second row? Because of your filter? jOOQ's MockDataProvider isn't an actual RDBMS. It mocks an RDBMS. You're returning the same result for *every* possible query, including SELECT 1 FROM DUAL. If you want the SQL statement to be interpreted, you have to either:

- Implement all that logic (but beware, don't take it too far, or you'll implement a full RDBMS eventually)
- Use an actual RDBMS and write integration tests rather than mocking

Hope this helps,
Lukas

Hagi Cohen

unread,
Sep 14, 2021, 3:39:16 AM9/14/21
to jooq...@googlegroups.com
Maybe do you have another layer on java will execute the query on the results?

You received this message because you are subscribed to a topic in the Google Groups "jOOQ User Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jooq-user/Kk5AduSPfhI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jooq-user+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jooq-user/CAB4ELO7tCGV30sJb8NBdSTweN-Ln4R-AzNUDKsTA-qDTL%2Bvn_Q%40mail.gmail.com.

Lukas Eder

unread,
Sep 14, 2021, 3:44:33 AM9/14/21
to jOOQ User Group
Hagi,

Why would jOOQ "execute" your query? jOOQ's isn't an RDBMS. But you can use an actual RDBMS. Does that make sense? :)

Cheers,
Lukas

Hagi Cohen

unread,
Sep 14, 2021, 3:47:18 AM9/14/21
to jooq...@googlegroups.com
I use the mocking jooq for mocking the RDBMS but now I need to move it out for a query.

I think jooq will give me all solution 

Lukas Eder

unread,
Sep 14, 2021, 4:02:12 AM9/14/21
to jOOQ User Group
Well, what can I say. jOOQ's mock API is what it is.

You can implement a single MockDataProvider that simulates those parts of your RDBMS that you wish to simulate. With an emphasis on *YOU* implement that. It's more convenient than doing that by implementing JDBC (where you'd have to implement tons of methods). With jOOQ, you have to implement only a single method.

You're not the first who thinks this somehow magically emulates an entire RDBMS, but where would we stop? WHERE? GROUP BY? COUNT(*) OVER (PARTITION BY x ORDER BY y ROWS BETWEEN 1 PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW)? MATCH_RECOGNIZE? Should we implement MVCC or 2PL transaction semantics, or both? Should we support concurrency at all?

I mean, jOOQ *could* implement all of an RDBMS, but why do that when there are already so many RDBMS out there?

What you're looking for is integration testing (e.g. use testcontainers.org). I don't think you really want to mock your database.
I hope this helps,
Lukas

Reply all
Reply to author
Forward
0 new messages