Closed StevenACoffman closed 2 months ago
Or a subset of the above example. A minimal variant would be:
struct
version of WithArgs
struct
version of AddRows
Hello.
Why cannot you just implement QueryRewriter interface for Params
struct and then use it as the argument?
Some examples are available here.
The current situation is that you have variadic args that are strongly typed but only fail in runtime, rather than at compile time. The variadic situation means that we get positional failures where code is working in production, but fail in the mock without good feedback as to what is wrong or how to correct it.
The same thing happens for the Rows
as for the Params
when they are mismatched. We get runtime failures that are hard to diagnose and correct.
We would like to pass structs for both WithArgs
and AddRows
and that will be both self-documenting and give compile-time insight into positional errors.
You can pass struct to WithArg
. Struct should implement QueryRewriter interface as I said. Or I don't understand your issue.
Check this test code:
func TestQueryRewriter(t *testing.T) {
t.Parallel()
mock, err := NewConn(QueryMatcherOption(QueryMatcherEqual))
a := assert.New(t)
a.NoError(err)
update := `UPDATE "user" SET email = @email, password = @password, updated_utc = @updated_utc WHERE id = @id`
mock.ExpectExec(update).WithArgs(pgx.NamedArgs{
"id": "mockUser.ID",
"email": "mockUser.Email",
"password": "mockUser.Password",
"updated_utc": AnyArg(),
}).WillReturnError(errPanic)
_, err = mock.Exec(context.Background(), update, pgx.NamedArgs{
"id": "mockUser.ID",
"email": "mockUser.Email",
"password": "mockUser.Password",
"updated_utc": time.Now().UTC(),
})
a.Error(err)
a.NoError(mock.ExpectationsWereMet())
}
That example works because NamedArgs
is also used as input to the actual query. However we use sqlc to generate a query interface. It provides methods which call Exec
/Query
with unpacked args. Maybe we could open an issue to that project to use QueryRewriter
when generating for pgx/v5
.
So, what about rows then? There is an identical issue where we have Row
structs for the actual queries, but no way to use them with AddRow{s}
mocks.
However we use sqlc to generate a query interface. It provides methods which call
Exec
/Query
with unpacked args.
I thought you are absolutely free to modify sqlc
template. This way you can implement QueryRewriter in the template, so every struct will have the method needed.
So, what about rows then?
Seems I missed that part completely. Would you please bring some example code? Thanks in advance!
We use
pgx/v5
with sqlc andpgxmock
, and we would like to contribute some convenience functions (written by my co-worker @coady) for this combination (without adding any new dependencies in pgxmock).sqlc will generate structs like the Params object that we can use with pgxmock.
Background
Given a SQL query like:
sqlc will generate a structs like Params and others that we can use with pgxmock.
We can then add a
structmock.go
:ExpectQuery
ExpectQuery
allows us to modify our tests to go from:to:
ExpectExec
ExpectExec
allows us to modify our tests to go from:to this:
Expect
Expect
allows us to modify our tests to go from:to this: