├── Makefile ├── .gitignore ├── go.mod ├── pgx_pool.go ├── testdata ├── main.go └── order.go ├── LICENCE ├── row.go ├── README.md ├── order_dao_example_test.go ├── go.sum ├── rows.go └── pgx_pool_mock.go /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all build run test clean watch docker-run docker-down itest 2 | 3 | # Regenerate the mock 4 | mock: 5 | @echo "Generating mock..." 6 | @echo "Installing mockgen from go.uber.org/mock/mockgen..." 7 | @go install go.uber.org/mock/mockgen@latest 8 | @mockgen -source=pgx_pool.go -destination="pgx_pool_mock.go" -package=pgxpoolmock -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # If you prefer the allow list template instead of the deny list, see community template: 2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore 3 | # 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.exe~ 7 | *.dll 8 | *.so 9 | *.dylib 10 | 11 | # Test binary, built with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Dependency directories (remove the comment below to include it) 18 | vendor/ 19 | 20 | # Go workspace file 21 | go.work 22 | go.work.sum 23 | 24 | # env file 25 | .env 26 | 27 | .idea 28 | .DS_Store -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/driftprogramming/pgxpoolmock 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/jackc/pgx/v5 v5.7.1 7 | github.com/stretchr/testify v1.10.0 8 | go.uber.org/mock v0.5.0 9 | ) 10 | 11 | require ( 12 | github.com/davecgh/go-spew v1.1.1 // indirect 13 | github.com/jackc/pgpassfile v1.0.0 // indirect 14 | github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect 15 | github.com/jackc/puddle/v2 v2.2.2 // indirect 16 | github.com/kr/text v0.2.0 // indirect 17 | github.com/pmezard/go-difflib v1.0.0 // indirect 18 | github.com/rogpeppe/go-internal v1.6.1 // indirect 19 | golang.org/x/crypto v0.27.0 // indirect 20 | golang.org/x/sync v0.8.0 // indirect 21 | golang.org/x/text v0.18.0 // indirect 22 | gopkg.in/yaml.v3 v3.0.1 // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /pgx_pool.go: -------------------------------------------------------------------------------- 1 | package pgxpoolmock 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/jackc/pgx/v5" 7 | "github.com/jackc/pgx/v5/pgconn" 8 | "github.com/jackc/pgx/v5/pgxpool" 9 | ) 10 | 11 | type PgxPool interface { 12 | Acquire(ctx context.Context) (*pgxpool.Conn, error) 13 | AcquireAllIdle(ctx context.Context) []*pgxpool.Conn 14 | AcquireFunc(ctx context.Context, f func(*pgxpool.Conn) error) error 15 | Begin(ctx context.Context) (pgx.Tx, error) 16 | BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, error) 17 | Close() 18 | Config() *pgxpool.Config 19 | CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) 20 | Exec(ctx context.Context, sql string, arguments ...any) (pgconn.CommandTag, error) 21 | Ping(ctx context.Context) error 22 | Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) 23 | QueryRow(ctx context.Context, sql string, args ...any) pgx.Row 24 | Reset() 25 | SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults 26 | Stat() *pgxpool.Stat 27 | } 28 | -------------------------------------------------------------------------------- /testdata/main.go: -------------------------------------------------------------------------------- 1 | package testdata 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/jackc/pgx/v5/pgxpool" 8 | ) 9 | 10 | func main() { 11 | connectionString := getConnectionString() 12 | realPool, _ := pgxpool.New(context.Background(), connectionString) 13 | orderDao := OrderDAO{ 14 | Pool: realPool, 15 | } 16 | order := orderDao.GetOrderByID(100) 17 | fmt.Print(order) 18 | } 19 | 20 | func getConnectionString() string { 21 | databaseHost := "10.0.20.101" 22 | databaseUser := "admin" 23 | databasePassword := "admin_password" 24 | databaseName := "orderdatabase" 25 | databaseConnectionPoolMaxSize := 100 26 | databaseConnectionPoolMinSize := 10 27 | defaultPoolHealthCheckPeriod := "10s" 28 | connectionString := fmt.Sprintf( 29 | "host=%s user=%s password=%s dbname=%s pool_max_conns=%d pool_min_conns=%d pool_health_check_period=%s", 30 | databaseHost, 31 | databaseUser, 32 | databasePassword, 33 | databaseName, 34 | databaseConnectionPoolMaxSize, 35 | databaseConnectionPoolMinSize, 36 | defaultPoolHealthCheckPeriod, 37 | ) 38 | 39 | return connectionString 40 | } 41 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Hejun Deng 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /testdata/order.go: -------------------------------------------------------------------------------- 1 | package testdata 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/driftprogramming/pgxpoolmock" 7 | ) 8 | 9 | type Order struct { 10 | ID int 11 | Price float64 12 | } 13 | 14 | type OrderDAO struct { 15 | Pool pgxpoolmock.PgxPool 16 | } 17 | 18 | func (dao *OrderDAO) InsertOrder(order *Order) error { 19 | _, err := dao.Pool.Exec(context.Background(), "insert into order (id, price) values ($1, $2)", order.ID, order.Price) 20 | if err != nil { 21 | return err 22 | } 23 | return nil 24 | } 25 | 26 | func (dao *OrderDAO) GetOneOrderByID(id int) (*Order, error) { 27 | order := &Order{} 28 | err := dao.Pool.QueryRow(context.Background(), "select id, price from order where id = $1", id). 29 | Scan(&order.ID, &order.Price) 30 | if err != nil { 31 | return nil, err 32 | } 33 | return order, nil 34 | } 35 | 36 | func (dao *OrderDAO) GetOrderByID(id int) *Order { 37 | rows, _ := dao.Pool.Query(context.Background(), "SELECT ID,Price FROM order WHERE ID =$1", id) 38 | for rows.Next() { 39 | order := &Order{} 40 | rows.Scan(&order.ID, &order.Price) 41 | return order 42 | } 43 | 44 | return nil 45 | } 46 | 47 | func (dao *OrderDAO) GetOrderMapByID(id int) map[string]interface{} { 48 | rows, _ := dao.Pool.Query(context.Background(), "SELECT ID,Price FROM order WHERE ID =$1", id) 49 | for rows.Next() { 50 | var id, price interface{} 51 | rows.Scan(&id, &price) 52 | order := map[string]interface{}{ 53 | "ID": id, 54 | "Price": price, 55 | } 56 | return order 57 | } 58 | 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /row.go: -------------------------------------------------------------------------------- 1 | package pgxpoolmock 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/jackc/pgx/v5/pgconn" 8 | ) 9 | 10 | func scanRow(row []interface{}, defs []pgconn.FieldDescription, dest ...interface{}) error { 11 | for i, col := range row { 12 | if dest[i] == nil { 13 | //behave compatible with pgx 14 | continue 15 | } 16 | destVal := reflect.ValueOf(dest[i]) 17 | if destVal.Kind() != reflect.Ptr { 18 | return fmt.Errorf("destination argument must be a pointer for column %s", defs[i].Name) 19 | } 20 | if col == nil { 21 | dest[i] = nil 22 | continue 23 | } 24 | val := reflect.ValueOf(col) 25 | 26 | destKind := destVal.Elem().Kind() 27 | if destKind == val.Kind() || destKind == reflect.Interface { 28 | if destElem := destVal.Elem(); destElem.CanSet() { 29 | destElem.Set(val) 30 | } else { 31 | return fmt.Errorf("cannot set destination value for column %s", string(defs[i].Name)) 32 | } 33 | } else { 34 | return fmt.Errorf("destination kind '%v' not supported for value kind '%v' of column '%s'", 35 | destKind, val.Kind(), string(defs[i].Name)) 36 | } 37 | } 38 | return nil 39 | } 40 | 41 | // Row is a mocked row that can be returned from QueryRow 42 | type Row struct { 43 | defs []pgconn.FieldDescription 44 | row []interface{} 45 | nextErr error 46 | closeErr error 47 | } 48 | 49 | func (r *Row) Scan(dest ...interface{}) error { 50 | if len(dest) != len(r.defs) { 51 | return fmt.Errorf("incorrect argument number %d for columns %d", len(dest), len(r.defs)) 52 | } 53 | err := scanRow(r.row, r.defs, dest...) 54 | if err != nil { 55 | return err 56 | } 57 | return r.nextErr 58 | } 59 | 60 | func NewRow(columns []string, values ...interface{}) *Row { 61 | var coldefs []pgconn.FieldDescription 62 | for _, column := range columns { 63 | coldefs = append(coldefs, pgconn.FieldDescription{Name: column}) 64 | } 65 | return &Row{ 66 | defs: coldefs, 67 | row: values, 68 | } 69 | } 70 | 71 | // RowError allows to set an error 72 | // which will be returned when the row is read 73 | func (r *Row) RowError(row int, err error) *Row { 74 | r.nextErr = err 75 | return r 76 | } 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### PGX POOL MOCK 2 | 3 | This repo is mock `pgxpool` in https://github.com/jackc/pgx. so that you can test your data access code locally, no real database is needed. 4 | I also strongly recommend you use `pgxpool` rather than `pgx` only. see https://github.com/jackc/pgx/tree/master/pgxpool 5 | 6 | ### How to install 7 | 8 | ``` 9 | go get -u github.com/driftprogramming/pgxpoolmock 10 | ``` 11 | 12 | ### How to Use 13 | 14 | See file `order_dao_example_test.go` to figure out how to use it. Or see the below: 15 | ```go 16 | package pgxpoolmock_test 17 | 18 | import ( 19 | "testing" 20 | 21 | "github.com/driftprogramming/pgxpoolmock" 22 | "github.com/driftprogramming/pgxpoolmock/testdata" 23 | "go.uber.org/mock/gomock" 24 | "github.com/stretchr/testify/assert" 25 | ) 26 | 27 | 28 | func TestInsertOrder(t *testing.T) { 29 | ctrl := gomock.NewController(t) 30 | defer ctrl.Finish() 31 | 32 | mockPool := pgxpoolmock.NewMockPgxPool(ctrl) 33 | commandTag := pgconn.CommandTag("INSERT 0 1") 34 | mockPool.EXPECT().Exec(gomock.Any(), "insert into order (id, price) values ($1, $2)", 1, 2.3).Return(commandTag, nil) 35 | orderDao := testdata.OrderDAO{ 36 | Pool: mockPool, 37 | } 38 | 39 | order := &testdata.Order{ 40 | ID: 1, 41 | Price: 2.3, 42 | } 43 | err := orderDao.InsertOrder(order) 44 | if err != nil { 45 | t.Fatalf("%v", err) 46 | } 47 | } 48 | 49 | func TestGetOneOrderByID(t *testing.T) { 50 | ctrl := gomock.NewController(t) 51 | defer ctrl.Finish() 52 | mockPool := pgxpoolmock.NewMockPgxPool(ctrl) 53 | columns := []string{"id", "price"} 54 | pgxRow := pgxpoolmock.NewRow(columns, 1, 2.3) 55 | mockPool.EXPECT().QueryRow(gomock.Any(), "select id, price from order where id = $1", 1).Return(pgxRow) 56 | orderDao := testdata.OrderDAO{ 57 | Pool: mockPool, 58 | } 59 | actualOrder, err := orderDao.GetOneOrderByID(1) 60 | if err != nil { 61 | t.Fatalf("%v", err) 62 | } 63 | assert.NotNil(t, actualOrder) 64 | assert.Equal(t, 1, actualOrder.ID) 65 | assert.Equal(t, 2.3, actualOrder.Price) 66 | } 67 | 68 | func TestName(t *testing.T) { 69 | t.Parallel() 70 | ctrl := gomock.NewController(t) 71 | defer ctrl.Finish() 72 | 73 | // given 74 | mockPool := pgxpoolmock.NewMockPgxPool(ctrl) 75 | columns := []string{"id", "price"} 76 | pgxRows := pgxpoolmock.NewRows(columns).AddRow(100, 100000.9).ToPgxRows() 77 | mockPool.EXPECT().Query(gomock.Any(), gomock.Any(), gomock.Any()).Return(pgxRows, nil) 78 | orderDao := testdata.OrderDAO{ 79 | Pool: mockPool, 80 | } 81 | 82 | // when 83 | actualOrder := orderDao.GetOrderByID(1) 84 | 85 | // then 86 | assert.NotNil(t, actualOrder) 87 | assert.Equal(t, 100, actualOrder.ID) 88 | assert.Equal(t, 100000.9, actualOrder.Price) 89 | } 90 | 91 | ``` 92 | -------------------------------------------------------------------------------- /order_dao_example_test.go: -------------------------------------------------------------------------------- 1 | package pgxpoolmock_test 2 | 3 | import ( 4 | "fmt" 5 | "go.uber.org/mock/gomock" 6 | "testing" 7 | 8 | "github.com/driftprogramming/pgxpoolmock" 9 | "github.com/driftprogramming/pgxpoolmock/testdata" 10 | "github.com/jackc/pgx/v5/pgconn" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestInsertOrder(t *testing.T) { 15 | ctrl := gomock.NewController(t) 16 | defer ctrl.Finish() 17 | 18 | mockPool := pgxpoolmock.NewMockPgxPool(ctrl) 19 | commandTag := pgconn.NewCommandTag("INSERT 0 1") 20 | mockPool.EXPECT().Exec(gomock.Any(), "insert into order (id, price) values ($1, $2)", 1, 2.3).Return(commandTag, nil) 21 | orderDao := testdata.OrderDAO{ 22 | Pool: mockPool, 23 | } 24 | 25 | order := &testdata.Order{ 26 | ID: 1, 27 | Price: 2.3, 28 | } 29 | err := orderDao.InsertOrder(order) 30 | if err != nil { 31 | t.Fatalf("%v", err) 32 | } 33 | } 34 | 35 | func TestGetOneOrderByID(t *testing.T) { 36 | ctrl := gomock.NewController(t) 37 | defer ctrl.Finish() 38 | mockPool := pgxpoolmock.NewMockPgxPool(ctrl) 39 | columns := []string{"id", "price"} 40 | pgxRow := pgxpoolmock.NewRow(columns, 1, 2.3) 41 | mockPool.EXPECT().QueryRow(gomock.Any(), "select id, price from order where id = $1", 1).Return(pgxRow) 42 | orderDao := testdata.OrderDAO{ 43 | Pool: mockPool, 44 | } 45 | actualOrder, err := orderDao.GetOneOrderByID(1) 46 | if err != nil { 47 | t.Fatalf("%v", err) 48 | } 49 | assert.NotNil(t, actualOrder) 50 | assert.Equal(t, 1, actualOrder.ID) 51 | assert.Equal(t, 2.3, actualOrder.Price) 52 | } 53 | 54 | func TestName(t *testing.T) { 55 | t.Parallel() 56 | ctrl := gomock.NewController(t) 57 | defer ctrl.Finish() 58 | 59 | // given 60 | mockPool := pgxpoolmock.NewMockPgxPool(ctrl) 61 | columns := []string{"id", "price"} 62 | pgxRows := pgxpoolmock.NewRows(columns).AddRow(100, 100000.9).ToPgxRows() 63 | mockPool.EXPECT().Query(gomock.Any(), gomock.Any(), gomock.Any()).Return(pgxRows, nil) 64 | orderDao := testdata.OrderDAO{ 65 | Pool: mockPool, 66 | } 67 | 68 | // when 69 | actualOrder := orderDao.GetOrderByID(1) 70 | 71 | // then 72 | assert.NotNil(t, actualOrder) 73 | assert.Equal(t, 100, actualOrder.ID) 74 | assert.Equal(t, 100000.9, actualOrder.Price) 75 | } 76 | 77 | func TestMap(t *testing.T) { 78 | t.Parallel() 79 | ctrl := gomock.NewController(t) 80 | defer ctrl.Finish() 81 | 82 | // given 83 | mockPool := pgxpoolmock.NewMockPgxPool(ctrl) 84 | columns := []string{"id", "price"} 85 | pgxRows := pgxpoolmock.NewRows(columns).AddRow(100, 100000.9).ToPgxRows() 86 | assert.NotEqual(t, "with empty rows", fmt.Sprintf("%s", pgxRows)) 87 | 88 | mockPool.EXPECT().Query(gomock.Any(), gomock.Any(), gomock.Any()).Return(pgxRows, nil) 89 | orderDao := testdata.OrderDAO{ 90 | Pool: mockPool, 91 | } 92 | 93 | // when 94 | actualOrder := orderDao.GetOrderMapByID(1) 95 | 96 | // then 97 | assert.NotNil(t, actualOrder) 98 | assert.Equal(t, 100, actualOrder["ID"]) 99 | assert.Equal(t, 100000.9, actualOrder["Price"]) 100 | } 101 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= 6 | github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= 7 | github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= 8 | github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= 9 | github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= 10 | github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= 11 | github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= 12 | github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= 13 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 14 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 15 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 16 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 17 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 18 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 19 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 20 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 21 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 22 | github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= 23 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 24 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 25 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 26 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 27 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 28 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 29 | go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= 30 | go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= 31 | golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= 32 | golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= 33 | golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= 34 | golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 35 | golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= 36 | golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 37 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 38 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 39 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 40 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 41 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 42 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 43 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 44 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 45 | -------------------------------------------------------------------------------- /rows.go: -------------------------------------------------------------------------------- 1 | package pgxpoolmock 2 | 3 | import ( 4 | "encoding/csv" 5 | "fmt" 6 | "github.com/jackc/pgx/v5" 7 | "io" 8 | "strings" 9 | 10 | "github.com/jackc/pgx/v5/pgconn" 11 | ) 12 | 13 | // CSVColumnParser is a function which converts trimmed csv 14 | // column string to a []byte representation. Currently 15 | // transforms NULL to nil 16 | var CSVColumnParser = func(s string) interface{} { 17 | switch { 18 | case strings.ToLower(s) == "null": 19 | return nil 20 | } 21 | return s 22 | } 23 | 24 | type rowSets struct { 25 | sets []*Rows 26 | pos int 27 | } 28 | 29 | func (rs *rowSets) Err() error { 30 | r := rs.sets[rs.pos] 31 | return r.nextErr[r.pos-1] 32 | } 33 | 34 | func (rs *rowSets) Conn() *pgx.Conn { 35 | return &pgx.Conn{} 36 | } 37 | 38 | func (rs *rowSets) CommandTag() pgconn.CommandTag { 39 | return pgconn.NewCommandTag("") 40 | } 41 | 42 | func (rs *rowSets) FieldDescriptions() []pgconn.FieldDescription { 43 | return rs.sets[rs.pos].defs 44 | } 45 | 46 | // func (rs *rowSets) Columns() []string { 47 | // return rs.sets[rs.pos].cols 48 | // } 49 | 50 | func (rs *rowSets) Close() { 51 | //rs.ex.rowsWereClosed = true 52 | // return rs.sets[rs.pos].closeErr 53 | } 54 | 55 | // advances to next row 56 | func (rs *rowSets) Next() bool { 57 | r := rs.sets[rs.pos] 58 | r.pos++ 59 | return r.pos <= len(r.rows) 60 | } 61 | 62 | func (rs *rowSets) Values() ([]interface{}, error) { 63 | return nil, nil 64 | } 65 | 66 | func (rs *rowSets) Scan(dest ...interface{}) error { 67 | r := rs.sets[rs.pos] 68 | if len(dest) != len(r.defs) { 69 | return fmt.Errorf("incorrect argument number %d for columns %d", len(dest), len(r.defs)) 70 | } 71 | if r.pos == 0 { 72 | return nil 73 | } 74 | err := scanRow(r.rows[r.pos-1], r.defs, dest...) 75 | if err != nil { 76 | return err 77 | } 78 | return r.nextErr[r.pos-1] 79 | } 80 | 81 | func (rs *rowSets) RawValues() [][]byte { 82 | r := rs.sets[rs.pos] 83 | dest := make([][]byte, len(r.defs)) 84 | 85 | for i, col := range r.rows[r.pos-1] { 86 | if b, ok := rawBytes(col); ok { 87 | dest[i] = b 88 | continue 89 | } 90 | dest[i] = col.([]byte) 91 | } 92 | 93 | return dest 94 | } 95 | 96 | // transforms to debuggable printable string 97 | func (rs *rowSets) String() string { 98 | if rs.empty() { 99 | return "with empty rows" 100 | } 101 | 102 | msg := "should return rows:\n" 103 | if len(rs.sets) == 1 { 104 | for n, row := range rs.sets[0].rows { 105 | msg += fmt.Sprintf(" row %d - %+v\n", n, row) 106 | } 107 | return strings.TrimSpace(msg) 108 | } 109 | for i, set := range rs.sets { 110 | msg += fmt.Sprintf(" result set: %d\n", i) 111 | for n, row := range set.rows { 112 | msg += fmt.Sprintf(" row %d - %+v\n", n, row) 113 | } 114 | } 115 | return strings.TrimSpace(msg) 116 | } 117 | 118 | func (rs *rowSets) empty() bool { 119 | for _, set := range rs.sets { 120 | if len(set.rows) > 0 { 121 | return false 122 | } 123 | } 124 | return true 125 | } 126 | 127 | func rawBytes(col interface{}) (_ []byte, ok bool) { 128 | val, ok := col.([]byte) 129 | if !ok || len(val) == 0 { 130 | return nil, false 131 | } 132 | // Copy the bytes from the mocked row into a shared raw buffer, which we'll replace the content of later 133 | // This allows scanning into sql.RawBytes to correctly become invalid on subsequent calls to Next(), Scan() or Close() 134 | b := make([]byte, len(val)) 135 | copy(b, val) 136 | return b, true 137 | } 138 | 139 | // Rows is a mocked collection of rows to 140 | // return for Query result 141 | type Rows struct { 142 | defs []pgconn.FieldDescription 143 | rows [][]interface{} 144 | pos int 145 | nextErr map[int]error 146 | closeErr error 147 | } 148 | 149 | // NewRows allows Rows to be created from a 150 | // sql interface{} slice or from the CSV string and 151 | // to be used as sql driver.Rows. 152 | // Use Sqlmock.NewRows instead if using a custom converter 153 | func NewRows(columns []string) *Rows { 154 | var coldefs []pgconn.FieldDescription 155 | for _, column := range columns { 156 | coldefs = append(coldefs, pgconn.FieldDescription{Name: column}) 157 | } 158 | return &Rows{ 159 | defs: coldefs, 160 | nextErr: make(map[int]error), 161 | } 162 | } 163 | 164 | // CloseError allows to set an error 165 | // which will be returned by rows.Close 166 | // function. 167 | // 168 | // The close error will be triggered only in cases 169 | // when rows.Next() EOF was not yet reached, that is 170 | // a default sql library behavior 171 | func (r *Rows) CloseError(err error) *Rows { 172 | r.closeErr = err 173 | return r 174 | } 175 | 176 | // RowError allows to set an error 177 | // which will be returned when a given 178 | // row number is read 179 | func (r *Rows) RowError(row int, err error) *Rows { 180 | r.nextErr[row] = err 181 | return r 182 | } 183 | 184 | // AddRow composed from database interface{} slice 185 | // return the same instance to perform subsequent actions. 186 | // Note that the number of values must match the number 187 | // of columns 188 | func (r *Rows) AddRow(values ...interface{}) *Rows { 189 | if len(values) != len(r.defs) { 190 | panic("Expected number of values to match number of columns") 191 | } 192 | 193 | row := make([]interface{}, len(r.defs)) 194 | copy(row, values) 195 | r.rows = append(r.rows, row) 196 | return r 197 | } 198 | 199 | func (r *Rows) ToPgxRows() pgx.Rows { 200 | pgxRows := convert(r) 201 | return pgxRows 202 | } 203 | 204 | // FromCSVString build rows from csv string. 205 | // return the same instance to perform subsequent actions. 206 | // Note that the number of values must match the number 207 | // of columns 208 | func (r *Rows) FromCSVString(s string) *Rows { 209 | res := strings.NewReader(strings.TrimSpace(s)) 210 | csvReader := csv.NewReader(res) 211 | 212 | for { 213 | res, err := csvReader.Read() 214 | if err != nil || res == nil { 215 | break 216 | } 217 | 218 | row := make([]interface{}, len(r.defs)) 219 | for i, v := range res { 220 | row[i] = CSVColumnParser(strings.TrimSpace(v)) 221 | } 222 | r.rows = append(r.rows, row) 223 | } 224 | return r 225 | } 226 | 227 | // Implement the "RowsNextResultSet" interface 228 | func (rs *rowSets) HasNextResultSet() bool { 229 | return rs.pos+1 < len(rs.sets) 230 | } 231 | 232 | // Implement the "RowsNextResultSet" interface 233 | func (rs *rowSets) NextResultSet() error { 234 | if !rs.HasNextResultSet() { 235 | return io.EOF 236 | } 237 | 238 | rs.pos++ 239 | return nil 240 | } 241 | 242 | // type for rows with columns definition created with sqlmock.NewRowsWithColumnDefinition 243 | type rowSetsWithDefinition struct { 244 | *rowSets 245 | } 246 | 247 | // NewRowsWithColumnDefinition return rows with columns metadata 248 | func NewRowsWithColumnDefinition(columns ...pgconn.FieldDescription) *Rows { 249 | return &Rows{ 250 | defs: columns, 251 | nextErr: make(map[int]error), 252 | } 253 | } 254 | 255 | func convert(rows ...*Rows) pgx.Rows { 256 | var pgxrows pgx.Rows 257 | defs := 0 258 | sets := make([]*Rows, len(rows)) 259 | for i, r := range rows { 260 | sets[i] = r 261 | if r.defs != nil { 262 | defs++ 263 | } 264 | } 265 | if defs > 0 && defs == len(sets) { 266 | pgxrows = &rowSetsWithDefinition{&rowSets{sets: sets}} 267 | } else { 268 | pgxrows = &rowSets{sets: sets} 269 | } 270 | 271 | return pgxrows 272 | } 273 | -------------------------------------------------------------------------------- /pgx_pool_mock.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: pgx_pool.go 3 | // 4 | // Generated by this command: 5 | // 6 | // mockgen -source=pgx_pool.go -destination=pgx_pool_mock.go -package=pgxpoolmock 7 | // 8 | 9 | // Package pgxpoolmock is a generated GoMock package. 10 | package pgxpoolmock 11 | 12 | import ( 13 | context "context" 14 | reflect "reflect" 15 | 16 | pgx "github.com/jackc/pgx/v5" 17 | pgconn "github.com/jackc/pgx/v5/pgconn" 18 | pgxpool "github.com/jackc/pgx/v5/pgxpool" 19 | gomock "go.uber.org/mock/gomock" 20 | ) 21 | 22 | // MockPgxPool is a mock of PgxPool interface. 23 | type MockPgxPool struct { 24 | ctrl *gomock.Controller 25 | recorder *MockPgxPoolMockRecorder 26 | isgomock struct{} 27 | } 28 | 29 | // MockPgxPoolMockRecorder is the mock recorder for MockPgxPool. 30 | type MockPgxPoolMockRecorder struct { 31 | mock *MockPgxPool 32 | } 33 | 34 | // NewMockPgxPool creates a new mock instance. 35 | func NewMockPgxPool(ctrl *gomock.Controller) *MockPgxPool { 36 | mock := &MockPgxPool{ctrl: ctrl} 37 | mock.recorder = &MockPgxPoolMockRecorder{mock} 38 | return mock 39 | } 40 | 41 | // EXPECT returns an object that allows the caller to indicate expected use. 42 | func (m *MockPgxPool) EXPECT() *MockPgxPoolMockRecorder { 43 | return m.recorder 44 | } 45 | 46 | // Acquire mocks base method. 47 | func (m *MockPgxPool) Acquire(ctx context.Context) (*pgxpool.Conn, error) { 48 | m.ctrl.T.Helper() 49 | ret := m.ctrl.Call(m, "Acquire", ctx) 50 | ret0, _ := ret[0].(*pgxpool.Conn) 51 | ret1, _ := ret[1].(error) 52 | return ret0, ret1 53 | } 54 | 55 | // Acquire indicates an expected call of Acquire. 56 | func (mr *MockPgxPoolMockRecorder) Acquire(ctx any) *gomock.Call { 57 | mr.mock.ctrl.T.Helper() 58 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Acquire", reflect.TypeOf((*MockPgxPool)(nil).Acquire), ctx) 59 | } 60 | 61 | // AcquireAllIdle mocks base method. 62 | func (m *MockPgxPool) AcquireAllIdle(ctx context.Context) []*pgxpool.Conn { 63 | m.ctrl.T.Helper() 64 | ret := m.ctrl.Call(m, "AcquireAllIdle", ctx) 65 | ret0, _ := ret[0].([]*pgxpool.Conn) 66 | return ret0 67 | } 68 | 69 | // AcquireAllIdle indicates an expected call of AcquireAllIdle. 70 | func (mr *MockPgxPoolMockRecorder) AcquireAllIdle(ctx any) *gomock.Call { 71 | mr.mock.ctrl.T.Helper() 72 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcquireAllIdle", reflect.TypeOf((*MockPgxPool)(nil).AcquireAllIdle), ctx) 73 | } 74 | 75 | // AcquireFunc mocks base method. 76 | func (m *MockPgxPool) AcquireFunc(ctx context.Context, f func(*pgxpool.Conn) error) error { 77 | m.ctrl.T.Helper() 78 | ret := m.ctrl.Call(m, "AcquireFunc", ctx, f) 79 | ret0, _ := ret[0].(error) 80 | return ret0 81 | } 82 | 83 | // AcquireFunc indicates an expected call of AcquireFunc. 84 | func (mr *MockPgxPoolMockRecorder) AcquireFunc(ctx, f any) *gomock.Call { 85 | mr.mock.ctrl.T.Helper() 86 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcquireFunc", reflect.TypeOf((*MockPgxPool)(nil).AcquireFunc), ctx, f) 87 | } 88 | 89 | // Begin mocks base method. 90 | func (m *MockPgxPool) Begin(ctx context.Context) (pgx.Tx, error) { 91 | m.ctrl.T.Helper() 92 | ret := m.ctrl.Call(m, "Begin", ctx) 93 | ret0, _ := ret[0].(pgx.Tx) 94 | ret1, _ := ret[1].(error) 95 | return ret0, ret1 96 | } 97 | 98 | // Begin indicates an expected call of Begin. 99 | func (mr *MockPgxPoolMockRecorder) Begin(ctx any) *gomock.Call { 100 | mr.mock.ctrl.T.Helper() 101 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Begin", reflect.TypeOf((*MockPgxPool)(nil).Begin), ctx) 102 | } 103 | 104 | // BeginTx mocks base method. 105 | func (m *MockPgxPool) BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, error) { 106 | m.ctrl.T.Helper() 107 | ret := m.ctrl.Call(m, "BeginTx", ctx, txOptions) 108 | ret0, _ := ret[0].(pgx.Tx) 109 | ret1, _ := ret[1].(error) 110 | return ret0, ret1 111 | } 112 | 113 | // BeginTx indicates an expected call of BeginTx. 114 | func (mr *MockPgxPoolMockRecorder) BeginTx(ctx, txOptions any) *gomock.Call { 115 | mr.mock.ctrl.T.Helper() 116 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginTx", reflect.TypeOf((*MockPgxPool)(nil).BeginTx), ctx, txOptions) 117 | } 118 | 119 | // Close mocks base method. 120 | func (m *MockPgxPool) Close() { 121 | m.ctrl.T.Helper() 122 | m.ctrl.Call(m, "Close") 123 | } 124 | 125 | // Close indicates an expected call of Close. 126 | func (mr *MockPgxPoolMockRecorder) Close() *gomock.Call { 127 | mr.mock.ctrl.T.Helper() 128 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPgxPool)(nil).Close)) 129 | } 130 | 131 | // Config mocks base method. 132 | func (m *MockPgxPool) Config() *pgxpool.Config { 133 | m.ctrl.T.Helper() 134 | ret := m.ctrl.Call(m, "Config") 135 | ret0, _ := ret[0].(*pgxpool.Config) 136 | return ret0 137 | } 138 | 139 | // Config indicates an expected call of Config. 140 | func (mr *MockPgxPoolMockRecorder) Config() *gomock.Call { 141 | mr.mock.ctrl.T.Helper() 142 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Config", reflect.TypeOf((*MockPgxPool)(nil).Config)) 143 | } 144 | 145 | // CopyFrom mocks base method. 146 | func (m *MockPgxPool) CopyFrom(ctx context.Context, tableName pgx.Identifier, columnNames []string, rowSrc pgx.CopyFromSource) (int64, error) { 147 | m.ctrl.T.Helper() 148 | ret := m.ctrl.Call(m, "CopyFrom", ctx, tableName, columnNames, rowSrc) 149 | ret0, _ := ret[0].(int64) 150 | ret1, _ := ret[1].(error) 151 | return ret0, ret1 152 | } 153 | 154 | // CopyFrom indicates an expected call of CopyFrom. 155 | func (mr *MockPgxPoolMockRecorder) CopyFrom(ctx, tableName, columnNames, rowSrc any) *gomock.Call { 156 | mr.mock.ctrl.T.Helper() 157 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CopyFrom", reflect.TypeOf((*MockPgxPool)(nil).CopyFrom), ctx, tableName, columnNames, rowSrc) 158 | } 159 | 160 | // Exec mocks base method. 161 | func (m *MockPgxPool) Exec(ctx context.Context, sql string, arguments ...any) (pgconn.CommandTag, error) { 162 | m.ctrl.T.Helper() 163 | varargs := []any{ctx, sql} 164 | for _, a := range arguments { 165 | varargs = append(varargs, a) 166 | } 167 | ret := m.ctrl.Call(m, "Exec", varargs...) 168 | ret0, _ := ret[0].(pgconn.CommandTag) 169 | ret1, _ := ret[1].(error) 170 | return ret0, ret1 171 | } 172 | 173 | // Exec indicates an expected call of Exec. 174 | func (mr *MockPgxPoolMockRecorder) Exec(ctx, sql any, arguments ...any) *gomock.Call { 175 | mr.mock.ctrl.T.Helper() 176 | varargs := append([]any{ctx, sql}, arguments...) 177 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exec", reflect.TypeOf((*MockPgxPool)(nil).Exec), varargs...) 178 | } 179 | 180 | // Ping mocks base method. 181 | func (m *MockPgxPool) Ping(ctx context.Context) error { 182 | m.ctrl.T.Helper() 183 | ret := m.ctrl.Call(m, "Ping", ctx) 184 | ret0, _ := ret[0].(error) 185 | return ret0 186 | } 187 | 188 | // Ping indicates an expected call of Ping. 189 | func (mr *MockPgxPoolMockRecorder) Ping(ctx any) *gomock.Call { 190 | mr.mock.ctrl.T.Helper() 191 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockPgxPool)(nil).Ping), ctx) 192 | } 193 | 194 | // Query mocks base method. 195 | func (m *MockPgxPool) Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error) { 196 | m.ctrl.T.Helper() 197 | varargs := []any{ctx, sql} 198 | for _, a := range args { 199 | varargs = append(varargs, a) 200 | } 201 | ret := m.ctrl.Call(m, "Query", varargs...) 202 | ret0, _ := ret[0].(pgx.Rows) 203 | ret1, _ := ret[1].(error) 204 | return ret0, ret1 205 | } 206 | 207 | // Query indicates an expected call of Query. 208 | func (mr *MockPgxPoolMockRecorder) Query(ctx, sql any, args ...any) *gomock.Call { 209 | mr.mock.ctrl.T.Helper() 210 | varargs := append([]any{ctx, sql}, args...) 211 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockPgxPool)(nil).Query), varargs...) 212 | } 213 | 214 | // QueryRow mocks base method. 215 | func (m *MockPgxPool) QueryRow(ctx context.Context, sql string, args ...any) pgx.Row { 216 | m.ctrl.T.Helper() 217 | varargs := []any{ctx, sql} 218 | for _, a := range args { 219 | varargs = append(varargs, a) 220 | } 221 | ret := m.ctrl.Call(m, "QueryRow", varargs...) 222 | ret0, _ := ret[0].(pgx.Row) 223 | return ret0 224 | } 225 | 226 | // QueryRow indicates an expected call of QueryRow. 227 | func (mr *MockPgxPoolMockRecorder) QueryRow(ctx, sql any, args ...any) *gomock.Call { 228 | mr.mock.ctrl.T.Helper() 229 | varargs := append([]any{ctx, sql}, args...) 230 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryRow", reflect.TypeOf((*MockPgxPool)(nil).QueryRow), varargs...) 231 | } 232 | 233 | // Reset mocks base method. 234 | func (m *MockPgxPool) Reset() { 235 | m.ctrl.T.Helper() 236 | m.ctrl.Call(m, "Reset") 237 | } 238 | 239 | // Reset indicates an expected call of Reset. 240 | func (mr *MockPgxPoolMockRecorder) Reset() *gomock.Call { 241 | mr.mock.ctrl.T.Helper() 242 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockPgxPool)(nil).Reset)) 243 | } 244 | 245 | // SendBatch mocks base method. 246 | func (m *MockPgxPool) SendBatch(ctx context.Context, b *pgx.Batch) pgx.BatchResults { 247 | m.ctrl.T.Helper() 248 | ret := m.ctrl.Call(m, "SendBatch", ctx, b) 249 | ret0, _ := ret[0].(pgx.BatchResults) 250 | return ret0 251 | } 252 | 253 | // SendBatch indicates an expected call of SendBatch. 254 | func (mr *MockPgxPoolMockRecorder) SendBatch(ctx, b any) *gomock.Call { 255 | mr.mock.ctrl.T.Helper() 256 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendBatch", reflect.TypeOf((*MockPgxPool)(nil).SendBatch), ctx, b) 257 | } 258 | 259 | // Stat mocks base method. 260 | func (m *MockPgxPool) Stat() *pgxpool.Stat { 261 | m.ctrl.T.Helper() 262 | ret := m.ctrl.Call(m, "Stat") 263 | ret0, _ := ret[0].(*pgxpool.Stat) 264 | return ret0 265 | } 266 | 267 | // Stat indicates an expected call of Stat. 268 | func (mr *MockPgxPoolMockRecorder) Stat() *gomock.Call { 269 | mr.mock.ctrl.T.Helper() 270 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stat", reflect.TypeOf((*MockPgxPool)(nil).Stat)) 271 | } 272 | --------------------------------------------------------------------------------