pgxmock v3.1 is out! Mocking named parameters for PostgreSQL in Go!

I am excited to announce the update of pgxmock v3.1! This update enables pgx.QueryRewriter interface support for mocking named parameters in your unit tests.

Named parameters? In Postgres?

The actual PostgreSQL $1 style placeholders are not that bad when only a few exist. But it rapidly gets challenging to manage when there are many of them, especially when specific arguments are used multiple times.

If you want to know how to use named parameters in your application with pgx and PostgreSQL, check the documentation.

Here’s a quick example of how to use named parameters in your code:

conn.Query(ctx, "select * from widgets where foo = @foo and bar = @bar",
    pgx.NamedArgs{"foo": 1, "bar": 2})

which is effectively the same as

conn.Query(ctx, "select * from widgets where foo = $1 and bar = $2", 1, 2)

Introducing WithRewrittenSQL to pgxmock expectations

The machinery of the pgx.QueryRewriter interface is supposed to rewrite the initial query and apply parameter values. Since in a real-life application, we may use custom implementations, not only provided by pgx.NamedArgs, we want to be able to check the final query. Exactly for this matter expectations ExpectedExec and ExpectedQuery provide WithRewrittenSQL method.

Example:

func TestInsertUser(t *testing.T) {
    t.Parallel()
    mock, err := NewConn(QueryMatcherOption(QueryMatcherEqual))
    if err != nil {
        t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
    }

    mock.ExpectExec("INSERT INTO users(name, created_at) VALUES (@name, @time)").
        WithArgs(pgx.NamedArgs{"name": "john", "time": pgxmock.AnyTime{}}).
// or   WithArgs(john", pgxmock.AnyTime{}).
        WithRewrittenSQL(`INSERT INTO users(name, created_at) VALUES ($1, $2)`).
        WillReturnResult(NewResult("INSERT", 1))

    _, err = mock.Exec(context.Background(),
        "INSERT INTO users(name, created_at) VALUES (@name, @time)",
        pgx.NamedArgs{"name": "john", "time": time.Now()},
    )
    if err != nil {
        t.Errorf("error '%s' was not expected, while inserting a row", err)
    }

    if err := mock.ExpectationsWereMet(); err != nil {
        t.Errorf("there were unfulfilled expectations: %s", err)
    }
}

As you can see in the example, the WithArgs method now supports the list of plain values and the pgx.QueryRewriter interface as the first argument.

Ready to Upgrade?

I motivate all users to upgrade to pgxmock v3.1 to take advantage of these exciting enhancements and improvements. Whether you’re a long-time user or just starting with pgxmock, these changes will advance your PostgreSQL mocking experience.

To get started with pgxmock v3.1, check your import statement:

import "github.com/pashagolub/pgxmock/v3"

and/or run

go get -u github.com/pashagolub/pgxmock/v3

Thank you for your continued support and feedback. I look forward to seeing how pgxmock v3.1 empowers your PostgreSQL database testing. If you have any questions or need assistance with the upgrade, please contact me on GitHub.

Happy mocking!

Truly yours, Pavlo Golub
Author of pgxmock 💙💛