Right, thank you! Your clarification is basically what I meant, but I
didn't express it too well I guess :D
As for my use-case, I suppose it was just an idea to implement an extra
check on the SQL query. jOOQ already generates classes based on the actual
tables, but when writing code there is nothing really stopping me from
writing a query that selects a set of columns but then tries to fetch the
result from a completely different column that was never queried for in the
first place.
Example:
dslContext.select(TBL_TASK.ID) //
.from(TBL_TASK) //
.where(TBL_TASK.ID.eq(taskId)) //
.fetchOne(TBL_TASK.STATE); // Not part of select!
Results in
IllegalArgumentException: Field ("db"."tbl_task"."state") is not contained
in Row ("db"."tbl_task"."id")
The mock-tests catches stuff like this, but I noticed that it didn't catch
me using the wrong column name altogether. It's a minor thing, but I was
curious to see if it would be possible to catch this scenario as well.
Anyway, thanks for the help so far, I've learned about some possible
pitfalls at least!
onsdag 29. november 2017 15.53.20 UTC+1 skrev Lukas Eder følgende:
>
>
>
> 2017-11-29 15:30 GMT+01:00 <[email protected] <javascript:>>:
>
>> Thank you, that helps somewhat. You're basically saying that me
>> specifying a column (fetchOne(state)) just fetches the first index instead,
>> yes? I verified this behavior by mocking a bad result where two columns
>> switched places (select(id, state) returns result "state,id").
>>
>
> No, be careful, that's not what I was saying. YOU specified that STATE was
> the column at the first index by *putting it there* in your select()
> clause. Again, fetchOne() has nothing to do with this. Here's the workflow:
>
> 1. select(STATE).fetchXYZ() runs a query expecting a STATE column at index
> 1 ... 1-based ;)
> 2. Because all the resulting rowtype information is known at compile time
> (because you put that column there), there's no need to look up whatever
> columns are returned by the database. We *expect* STATE to be the column at
> index 1.
> 3. Your MockDataProvider happens to produce a row with exactly 1 column.
> That might as well be a coincidence.
> 4. fetchLazy() (called internally by fetchOne()) now ignores column names
> and fetches only one column from index 1, again, because YOU said so.
> 5. fetchOne(STATE) is simply convenience API to map the
> Result<Record1<Integer>> result to a more convenient List<Integer> type by
> looking up the STATE column from the result of 4.
>
> Step 3 is important! MockDataProvider mocks your entire database for *ALL*
> the queries that are sent through the MockConnection. Try it with JDBC
> directly:
>
> try (Connection c = new MockConnection(...);
> Statement s = c.createStatement();
> ResultSet rs = s.executeQuery("blah")) {
> while (rs.next())
> System.out.println(rs.getString(1));
> }
>
>
> Now, it really doesn't matter if you replace "blah" by "SELECT STATE" ..
> or by "SELECT ID". Since you're selecting only one column (index 1),
> whatever is returned at index 1 will be placed in that column.
>
> Why don't you just step through the library with a debugger (specifically
> the MockDataProvider part). You'll see it will all make sense.
>
> I am still a bit unsure about the correct approach to writing a test that
>> verifies that the query is selecting the correct column name (ignoring the
>> topic of whether there is any real point to doing this in the first place).
>> Maybe it's more effort than it's actually worth?
>>
>
> I don't know what your use-case is. In general: I doubt that mocking is
> the correct approach to testing jOOQ and/or the database. An integration
> test with an actual database and an actual table might be simpler...
>
> It's not a huge deal really, but as a jOOQ-rookie I figured I should try
>> to figure out if it is doable
>>
>
> Well, using one of the more advanced lower level SPIs might be a bit more
> challenging a task for a jOOQ-rookie, so you might have simply not chosen
> the easiest challenge to start working with jOOQ with :)
>
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.