Skip to content

Commit

Permalink
[*] make Expect* methods visible in the docs, closes #181 (#182)
Browse files Browse the repository at this point in the history
* [*] make `Expect*` methods visible in the docs, closes #181
- rename `pgxMockIface` to `Expecter`
- rename `pgxIface` to `PgxCommonIface`
- move `Config()` methods to proper interfaces
- make `expectation` hidden
- cover `pgxmockConn.Config()` with test
  • Loading branch information
pashagolub authored Dec 21, 2023
1 parent e25d925 commit 7447a72
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 52 deletions.
9 changes: 9 additions & 0 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"

pgx "github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
)

Expand All @@ -19,6 +20,10 @@ func NewConn(options ...func(*pgxmock) error) (PgxConnIface, error) {
return smock, smock.open(options)
}

func (c *pgxmockConn) Config() *pgx.ConnConfig {
return &pgx.ConnConfig{}
}

type pgxmockPool struct {
pgxmock
}
Expand All @@ -39,6 +44,10 @@ func (p *pgxmockPool) Acquire(context.Context) (*pgxpool.Conn, error) {
return nil, errors.New("pgpool.Acquire() method is not implemented")
}

func (p *pgxmockPool) Config() *pgxpool.Config {
return &pgxpool.Config{}
}

// AsConn is similar to Acquire but returns proper mocking interface
func (p *pgxmockPool) AsConn() PgxConnIface {
return &pgxmockConn{pgxmock: p.pgxmock}
Expand Down
4 changes: 2 additions & 2 deletions expectations.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
pgconn "github.com/jackc/pgx/v5/pgconn"
)

// an Expectation interface
type Expectation interface {
// an expectation interface
type expectation interface {
error() error
required() bool
fulfilled() bool
Expand Down
75 changes: 29 additions & 46 deletions pgxmock.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ import (
pgxpool "github.com/jackc/pgx/v5/pgxpool"
)

// pgxMockIface interface serves to create expectations
// Expecter interface serves to create expectations
// for any kind of database action in order to mock
// and test real database behavior.
type pgxMockIface interface {
// ExpectClose queues an expectation for this database
// action to be triggered. the *ExpectedClose allows
// to mock database response
ExpectClose() *ExpectedClose

type Expecter interface {
// ExpectationsWereMet checks whether all queued expectations
// were met in order (unless MatchExpectationsInOrder set to false).
// If any of them was not met - an error is returned.
ExpectationsWereMet() error

// ExpectClose queues an expectation for this database
// action to be triggered. The *ExpectedClose allows
// to mock database response
ExpectClose() *ExpectedClose

// ExpectPrepare expects Prepare() to be called with expectedSQL query.
// the *ExpectedPrepare allows to mock database response.
// Note that you may expect Query() or Exec() on the *ExpectedPrepare
Expand Down Expand Up @@ -68,19 +68,12 @@ type pgxMockIface interface {
// the *ExpectedRollback allows to mock database response
ExpectRollback() *ExpectedRollback

// ExpectPing expected pgx.Conn.Ping to be called.
// the *ExpectedPing allows to mock database response
//
// Ping support only exists in the SQL library in Go 1.8 and above.
// ExpectPing in Go <=1.7 will return an ExpectedPing but not register
// any expectations.
//
// You must enable pings using MonitorPingsOption for this to register
// any expectations.
// ExpectPing expected Ping() to be called.
// The *ExpectedPing allows to mock database response
ExpectPing() *ExpectedPing

// ExpectCopyFrom expects pgx.CopyFrom to be called.
// the *ExpectCopyFrom allows to mock database response
// The *ExpectCopyFrom allows to mock database response
ExpectCopyFrom(expectedTableName pgx.Identifier, expectedColumns []string) *ExpectedCopyFrom

// MatchExpectationsInOrder gives an option whether to match all
Expand All @@ -96,62 +89,52 @@ type pgxMockIface interface {
// expectations will be expected in order
MatchExpectationsInOrder(bool)

// NewRows allows Rows to be created from a
// sql driver.Value slice or from the CSV string and
// to be used as sql driver.Rows.
// NewRows allows Rows to be created from a []string slice.
NewRows(columns []string) *Rows

// NewRowsWithColumnDefinition allows Rows to be created from a
// sql driver.Value slice with a definition of sql metadata
// pgconn.FieldDescription slice with a definition of sql metadata
NewRowsWithColumnDefinition(columns ...pgconn.FieldDescription) *Rows

// New Column allows to create a Column
NewColumn(name string) *pgconn.FieldDescription

Config() *pgxpool.Config

PgConn() *pgconn.PgConn
}

type pgxIface interface {
pgxMockIface
Begin(context.Context) (pgx.Tx, error)
// PgxCommonIface represents common interface for all pgx connection interfaces:
// pgxpool.Pool, pgx.Conn and pgx.Tx
type PgxCommonIface interface {
Expecter
pgx.Tx
BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, error)
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
Ping(context.Context) error
Prepare(context.Context, string, string) (*pgconn.StatementDescription, error)
PgConn() *pgconn.PgConn
}

// PgxConnIface represents pgx.Conn specific interface
type PgxConnIface interface {
pgxIface
pgx.Tx
PgxCommonIface
Close(ctx context.Context) error
Deallocate(ctx context.Context, name string) error
Config() *pgx.ConnConfig
PgConn() *pgconn.PgConn
}

// PgxPoolIface represents pgxpool.Pool specific interface
type PgxPoolIface interface {
pgxIface
pgx.Tx
PgxCommonIface
Acquire(ctx context.Context) (*pgxpool.Conn, error)
AcquireAllIdle(ctx context.Context) []*pgxpool.Conn
AcquireFunc(ctx context.Context, f func(*pgxpool.Conn) error) error
AsConn() PgxConnIface
Close()
Stat() *pgxpool.Stat
Reset()
Config() *pgxpool.Config
}

type pgxmock struct {
ordered bool
queryMatcher QueryMatcher
expectations []Expectation
}

func (c *pgxmock) Config() *pgxpool.Config {
return &pgxpool.Config{}
expectations []expectation
}

func (c *pgxmock) AcquireAllIdle(_ context.Context) []*pgxpool.Conn {
Expand Down Expand Up @@ -504,12 +487,12 @@ func (c *pgxmock) Reset() {
_ = ex.waitForDelay(context.Background())
}

type ExpectationType[t any] interface {
type expectationType[t any] interface {
*t
Expectation
expectation
}

func findExpectationFunc[ET ExpectationType[t], t any](c *pgxmock, method string, cmp func(ET) error) (ET, error) {
func findExpectationFunc[ET expectationType[t], t any](c *pgxmock, method string, cmp func(ET) error) (ET, error) {
var expected ET
var fulfilled int
var ok bool
Expand Down Expand Up @@ -555,6 +538,6 @@ func findExpectationFunc[ET ExpectationType[t], t any](c *pgxmock, method string
return expected, nil
}

func findExpectation[ET ExpectationType[t], t any](c *pgxmock, method string) (ET, error) {
func findExpectation[ET expectationType[t], t any](c *pgxmock, method string) (ET, error) {
return findExpectationFunc[ET, t](c, method, func(_ ET) error { return nil })
}
10 changes: 6 additions & 4 deletions pgxmock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/assert"
)

func cancelOrder(db pgxIface, orderID int) error {
func cancelOrder(db PgxCommonIface, orderID int) error {
tx, _ := db.Begin(context.Background())
_, _ = tx.Query(context.Background(), "SELECT * FROM orders {0} FOR UPDATE", orderID)
err := tx.Rollback(context.Background())
Expand Down Expand Up @@ -1143,7 +1143,7 @@ func TestQueryWithTimeout(t *testing.T) {
}
}

func queryWithTimeout(t time.Duration, db pgxIface, query string, args ...interface{}) (pgx.Rows, error) {
func queryWithTimeout(t time.Duration, db PgxCommonIface, query string, args ...interface{}) (pgx.Rows, error) {
rowsChan := make(chan pgx.Rows, 1)
errChan := make(chan error, 1)

Expand All @@ -1170,7 +1170,7 @@ func TestUnmockedMethods(t *testing.T) {
mock, _ := NewPool()
a := assert.New(t)
a.NotNil(mock.Config())
a.NotNil(mock.PgConn())
a.NotNil(mock.AsConn().Config())
a.NotNil(mock.AcquireAllIdle(ctx))
a.Nil(mock.AcquireFunc(ctx, func(*pgxpool.Conn) error { return nil }))
a.Nil(mock.SendBatch(ctx, nil))
Expand All @@ -1180,8 +1180,10 @@ func TestUnmockedMethods(t *testing.T) {

func TestNewRowsWithColumnDefinition(t *testing.T) {
mock, _ := NewConn()
a := assert.New(t)
a.NotNil(mock.PgConn())
r := mock.NewRowsWithColumnDefinition(*mock.NewColumn("foo"))
assert.Equal(t, 1, len(r.defs))
a.Equal(1, len(r.defs))
}

func TestExpectReset(t *testing.T) {
Expand Down

0 comments on commit 7447a72

Please sign in to comment.