pgx icon indicating copy to clipboard operation
pgx copied to clipboard

Mock pgx rows

Open Shobana-tech opened this issue 4 years ago • 6 comments

We used sqlmock package to mock sql rows. we currently replaced database/sql with pgx package. We tried to replace sqlmock for pgx.rows. But we are not able to find any suitable code to replace this. Here is our sample code with sqlmock

func testMethod *sql.Rows {
 db, mock, _ := sqlmock.New()
 mockRows := sqlmock.NewRows([]string{"test"}).AddRow("1")
 mock.ExpectQuery("select").WillReturnRows(mockRows)
 rows, _ := db.Query("select")
 defer db.Close()
 return rows

}

Is any workaround for this??

Shobana-tech avatar Mar 23 '20 08:03 Shobana-tech

The pgx interfaces would allow such a mocking package to be built but I do not know of any.

jackc avatar Mar 23 '20 21:03 jackc

@Shobana-tech You can try my work on this: https://github.com/pashagolub/pgxmock

@jackc Is it possible to introduce more interfaces into pgx, e.g.


type pgxIface interface {
	Begin(context.Context) (pgx.Tx, error)
	Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
	QueryRow(context.Context, string, ...interface{}) pgx.Row
	Query(context.Context, string, ...interface{}) (pgx.Rows, error)
	Ping(context.Context) error
	Prepare(context.Context, string, string) (*pgconn.StatementDescription, error)
	Deallocate(ctx context.Context, name string) error
}

type PgxConnIface interface {
	pgxIface
	Close(ctx context.Context) error
}
type PgxPoolIface interface {
	pgxIface
	Acquire(ctx context.Context) (*pgxpool.Conn, error)
	Close()
}

Changine Acquire to return interface instead of *pgxpool.Conn might help a lot. Right now pgxmock returns "not supported" error.

Thanks in advance!

pashagolub avatar Feb 22 '21 12:02 pashagolub

An general database interface like your pgxIface is possible, but changing Acquire to return an interface instead of a *pgxpool.Conn would be a breaking change. However, I think it would be possible to wrap pgxpool.Pool in your own type with that behavior.

jackc avatar Feb 22 '21 14:02 jackc

Yeah, but the idea is not to introduce additional types but to use native pgx types as much as possible. Thanks

pashagolub avatar Feb 22 '21 14:02 pashagolub

You guys also can take look at this repo, to mock pgxpools, it works for me: https://github.com/driftprogramming/pgxpoolmock

func TestName(t *testing.T) {
	t.Parallel()
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	// given
	mockPool := pgxpoolmock.NewMockPgxPool(ctrl)
	columns := []string{"id", "price"}
	pgxRows := pgxpoolmock.NewRows(columns).AddRow(100, 100000.9).ToPgxRows()
	mockPool.EXPECT().Query(gomock.Any(), gomock.Any(), gomock.Any()).Return(pgxRows, nil)
	orderDao := testdata.OrderDAO{
		Pool: mockPool,
	}

	// when
	actualOrder := orderDao.GetOrderByID(1)

	// then
	assert.NotNil(t, actualOrder)
	assert.Equal(t, 100, actualOrder.ID)
	assert.Equal(t, 100000.9, actualOrder.Price)
}

denghejun avatar Jun 04 '21 06:06 denghejun

Since pgxpoolmock mentioned above apparently is not maintained anymore and does not support v5, the same can be done with pgxmock with the .Kind() func, e.g.:

    import (
        "github.com/pashagolub/pgxmock/v3"
    )
    // ...
    columns := []string{"id"}
    pgxRows := pgxmock.NewRows(columns).AddRow(1).Kind()

renanferr avatar Nov 28 '23 21:11 renanferr