You've already forked go-sqlxmock
mirror of
https://github.com/zhashkevych/go-sqlxmock.git
synced 2025-06-12 21:47:29 +02:00
do not expose sql driver methods for sqlmock, give interface
This commit is contained in:
128
sqlmock.go
128
sqlmock.go
@ -18,11 +18,48 @@ import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Sqlmock type satisfies required sql.driver interfaces
|
||||
// to simulate actual database and also serves to
|
||||
// create expectations for any kind of database action
|
||||
// in order to mock and test real database behavior.
|
||||
type Sqlmock struct {
|
||||
// Sqlmock interface serves to create expectations
|
||||
// for any kind of database action in order to mock
|
||||
// and test real database behavior.
|
||||
type Sqlmock interface {
|
||||
|
||||
// ExpectClose queues an expectation for this database
|
||||
// action to be triggered. the *ExpectedClose allows
|
||||
// to mock database response
|
||||
ExpectClose() *ExpectedClose
|
||||
|
||||
// ExpectationsWereMet checks whether all queued expectations
|
||||
// were met in order. If any of them was not met - an error is returned.
|
||||
ExpectationsWereMet() error
|
||||
|
||||
// ExpectPrepare expects Prepare() to be called with sql query
|
||||
// which match sqlRegexStr given regexp.
|
||||
// the *ExpectedPrepare allows to mock database response.
|
||||
// Note that you may expect Query() or Exec() on the *ExpectedPrepare
|
||||
// statement to prevent repeating sqlRegexStr
|
||||
ExpectPrepare(sqlRegexStr string) *ExpectedPrepare
|
||||
|
||||
// ExpectQuery expects Query() or QueryRow() to be called with sql query
|
||||
// which match sqlRegexStr given regexp.
|
||||
// the *ExpectedQuery allows to mock database response.
|
||||
ExpectQuery(sqlRegexStr string) *ExpectedQuery
|
||||
|
||||
// ExpectExec expects Exec() to be called with sql query
|
||||
// which match sqlRegexStr given regexp.
|
||||
// the *ExpectedExec allows to mock database response
|
||||
ExpectExec(sqlRegexStr string) *ExpectedExec
|
||||
|
||||
// ExpectBegin expects *sql.DB.Begin to be called.
|
||||
// the *ExpectedBegin allows to mock database response
|
||||
ExpectBegin() *ExpectedBegin
|
||||
|
||||
// ExpectCommit expects *sql.Tx.Commit to be called.
|
||||
// the *ExpectedCommit allows to mock database response
|
||||
ExpectCommit() *ExpectedCommit
|
||||
|
||||
// ExpectRollback expects *sql.Tx.Rollback to be called.
|
||||
// the *ExpectedRollback allows to mock database response
|
||||
ExpectRollback() *ExpectedRollback
|
||||
|
||||
// MatchExpectationsInOrder gives an option whether to match all
|
||||
// expectations in the order they were set or not.
|
||||
@ -30,29 +67,33 @@ type Sqlmock struct {
|
||||
// By default it is set to - true. But if you use goroutines
|
||||
// to parallelize your query executation, that option may
|
||||
// be handy.
|
||||
MatchExpectationsInOrder bool
|
||||
MatchExpectationsInOrder(bool)
|
||||
}
|
||||
|
||||
dsn string
|
||||
opened int
|
||||
drv *mockDriver
|
||||
type sqlmock struct {
|
||||
ordered bool
|
||||
dsn string
|
||||
opened int
|
||||
drv *mockDriver
|
||||
|
||||
expected []expectation
|
||||
}
|
||||
|
||||
// ExpectClose queues an expectation for this database
|
||||
// action to be triggered. the *ExpectedClose allows
|
||||
// to mock database response
|
||||
func (c *Sqlmock) ExpectClose() *ExpectedClose {
|
||||
func (c *sqlmock) ExpectClose() *ExpectedClose {
|
||||
e := &ExpectedClose{}
|
||||
c.expected = append(c.expected, e)
|
||||
return e
|
||||
}
|
||||
|
||||
func (c *sqlmock) MatchExpectationsInOrder(b bool) {
|
||||
c.ordered = b
|
||||
}
|
||||
|
||||
// Close a mock database driver connection. It may or may not
|
||||
// be called depending on the sircumstances, but if it is called
|
||||
// there must be an *ExpectedClose expectation satisfied.
|
||||
// meets http://golang.org/pkg/database/sql/driver/#Conn interface
|
||||
func (c *Sqlmock) Close() error {
|
||||
func (c *sqlmock) Close() error {
|
||||
c.drv.Lock()
|
||||
defer c.drv.Unlock()
|
||||
|
||||
@ -77,7 +118,7 @@ func (c *Sqlmock) Close() error {
|
||||
}
|
||||
|
||||
next.Unlock()
|
||||
if c.MatchExpectationsInOrder {
|
||||
if c.ordered {
|
||||
return fmt.Errorf("call to database Close, was not expected, next expectation is: %s", next)
|
||||
}
|
||||
}
|
||||
@ -95,9 +136,7 @@ func (c *Sqlmock) Close() error {
|
||||
return expected.err
|
||||
}
|
||||
|
||||
// ExpectationsWereMet checks whether all queued expectations
|
||||
// were met in order. If any of them was not met - an error is returned.
|
||||
func (c *Sqlmock) ExpectationsWereMet() error {
|
||||
func (c *sqlmock) ExpectationsWereMet() error {
|
||||
for _, e := range c.expected {
|
||||
if !e.fulfilled() {
|
||||
return fmt.Errorf("there is a remaining expectation which was not matched: %s", e)
|
||||
@ -107,7 +146,7 @@ func (c *Sqlmock) ExpectationsWereMet() error {
|
||||
}
|
||||
|
||||
// Begin meets http://golang.org/pkg/database/sql/driver/#Conn interface
|
||||
func (c *Sqlmock) Begin() (driver.Tx, error) {
|
||||
func (c *sqlmock) Begin() (driver.Tx, error) {
|
||||
var expected *ExpectedBegin
|
||||
var ok bool
|
||||
var fulfilled int
|
||||
@ -124,7 +163,7 @@ func (c *Sqlmock) Begin() (driver.Tx, error) {
|
||||
}
|
||||
|
||||
next.Unlock()
|
||||
if c.MatchExpectationsInOrder {
|
||||
if c.ordered {
|
||||
return nil, fmt.Errorf("call to database transaction Begin, was not expected, next expectation is: %s", next)
|
||||
}
|
||||
}
|
||||
@ -141,16 +180,14 @@ func (c *Sqlmock) Begin() (driver.Tx, error) {
|
||||
return c, expected.err
|
||||
}
|
||||
|
||||
// ExpectBegin expects *sql.DB.Begin to be called.
|
||||
// the *ExpectedBegin allows to mock database response
|
||||
func (c *Sqlmock) ExpectBegin() *ExpectedBegin {
|
||||
func (c *sqlmock) ExpectBegin() *ExpectedBegin {
|
||||
e := &ExpectedBegin{}
|
||||
c.expected = append(c.expected, e)
|
||||
return e
|
||||
}
|
||||
|
||||
// Exec meets http://golang.org/pkg/database/sql/driver/#Execer
|
||||
func (c *Sqlmock) Exec(query string, args []driver.Value) (res driver.Result, err error) {
|
||||
func (c *sqlmock) Exec(query string, args []driver.Value) (res driver.Result, err error) {
|
||||
query = stripQuery(query)
|
||||
var expected *ExpectedExec
|
||||
var fulfilled int
|
||||
@ -163,7 +200,7 @@ func (c *Sqlmock) Exec(query string, args []driver.Value) (res driver.Result, er
|
||||
continue
|
||||
}
|
||||
|
||||
if c.MatchExpectationsInOrder {
|
||||
if c.ordered {
|
||||
if expected, ok = next.(*ExpectedExec); ok {
|
||||
break
|
||||
}
|
||||
@ -218,10 +255,7 @@ func (c *Sqlmock) Exec(query string, args []driver.Value) (res driver.Result, er
|
||||
return expected.result, err
|
||||
}
|
||||
|
||||
// ExpectExec expects Exec() to be called with sql query
|
||||
// which match sqlRegexStr given regexp.
|
||||
// the *ExpectedExec allows to mock database response
|
||||
func (c *Sqlmock) ExpectExec(sqlRegexStr string) *ExpectedExec {
|
||||
func (c *sqlmock) ExpectExec(sqlRegexStr string) *ExpectedExec {
|
||||
e := &ExpectedExec{}
|
||||
e.sqlRegex = regexp.MustCompile(sqlRegexStr)
|
||||
c.expected = append(c.expected, e)
|
||||
@ -229,7 +263,7 @@ func (c *Sqlmock) ExpectExec(sqlRegexStr string) *ExpectedExec {
|
||||
}
|
||||
|
||||
// Prepare meets http://golang.org/pkg/database/sql/driver/#Conn interface
|
||||
func (c *Sqlmock) Prepare(query string) (driver.Stmt, error) {
|
||||
func (c *sqlmock) Prepare(query string) (driver.Stmt, error) {
|
||||
var expected *ExpectedPrepare
|
||||
var fulfilled int
|
||||
var ok bool
|
||||
@ -246,7 +280,7 @@ func (c *Sqlmock) Prepare(query string) (driver.Stmt, error) {
|
||||
}
|
||||
|
||||
next.Unlock()
|
||||
if c.MatchExpectationsInOrder {
|
||||
if c.ordered {
|
||||
return nil, fmt.Errorf("call to Prepare stetement with query '%s', was not expected, next expectation is: %s", query, next)
|
||||
}
|
||||
}
|
||||
@ -265,19 +299,14 @@ func (c *Sqlmock) Prepare(query string) (driver.Stmt, error) {
|
||||
return &statement{c, query, expected.closeErr}, expected.err
|
||||
}
|
||||
|
||||
// ExpectPrepare expects Prepare() to be called with sql query
|
||||
// which match sqlRegexStr given regexp.
|
||||
// the *ExpectedPrepare allows to mock database response.
|
||||
// Note that you may expect Query() or Exec() on the *ExpectedPrepare
|
||||
// statement to prevent repeating sqlRegexStr
|
||||
func (c *Sqlmock) ExpectPrepare(sqlRegexStr string) *ExpectedPrepare {
|
||||
func (c *sqlmock) ExpectPrepare(sqlRegexStr string) *ExpectedPrepare {
|
||||
e := &ExpectedPrepare{sqlRegex: regexp.MustCompile(sqlRegexStr), mock: c}
|
||||
c.expected = append(c.expected, e)
|
||||
return e
|
||||
}
|
||||
|
||||
// Query meets http://golang.org/pkg/database/sql/driver/#Queryer
|
||||
func (c *Sqlmock) Query(query string, args []driver.Value) (rw driver.Rows, err error) {
|
||||
func (c *sqlmock) Query(query string, args []driver.Value) (rw driver.Rows, err error) {
|
||||
query = stripQuery(query)
|
||||
var expected *ExpectedQuery
|
||||
var fulfilled int
|
||||
@ -290,7 +319,7 @@ func (c *Sqlmock) Query(query string, args []driver.Value) (rw driver.Rows, err
|
||||
continue
|
||||
}
|
||||
|
||||
if c.MatchExpectationsInOrder {
|
||||
if c.ordered {
|
||||
if expected, ok = next.(*ExpectedQuery); ok {
|
||||
break
|
||||
}
|
||||
@ -347,34 +376,27 @@ func (c *Sqlmock) Query(query string, args []driver.Value) (rw driver.Rows, err
|
||||
return expected.rows, err
|
||||
}
|
||||
|
||||
// ExpectQuery expects Query() or QueryRow() to be called with sql query
|
||||
// which match sqlRegexStr given regexp.
|
||||
// the *ExpectedQuery allows to mock database response.
|
||||
func (c *Sqlmock) ExpectQuery(sqlRegexStr string) *ExpectedQuery {
|
||||
func (c *sqlmock) ExpectQuery(sqlRegexStr string) *ExpectedQuery {
|
||||
e := &ExpectedQuery{}
|
||||
e.sqlRegex = regexp.MustCompile(sqlRegexStr)
|
||||
c.expected = append(c.expected, e)
|
||||
return e
|
||||
}
|
||||
|
||||
// ExpectCommit expects *sql.Tx.Commit to be called.
|
||||
// the *ExpectedCommit allows to mock database response
|
||||
func (c *Sqlmock) ExpectCommit() *ExpectedCommit {
|
||||
func (c *sqlmock) ExpectCommit() *ExpectedCommit {
|
||||
e := &ExpectedCommit{}
|
||||
c.expected = append(c.expected, e)
|
||||
return e
|
||||
}
|
||||
|
||||
// ExpectRollback expects *sql.Tx.Rollback to be called.
|
||||
// the *ExpectedRollback allows to mock database response
|
||||
func (c *Sqlmock) ExpectRollback() *ExpectedRollback {
|
||||
func (c *sqlmock) ExpectRollback() *ExpectedRollback {
|
||||
e := &ExpectedRollback{}
|
||||
c.expected = append(c.expected, e)
|
||||
return e
|
||||
}
|
||||
|
||||
// Commit meets http://golang.org/pkg/database/sql/driver/#Tx
|
||||
func (c *Sqlmock) Commit() error {
|
||||
func (c *sqlmock) Commit() error {
|
||||
var expected *ExpectedCommit
|
||||
var fulfilled int
|
||||
var ok bool
|
||||
@ -391,7 +413,7 @@ func (c *Sqlmock) Commit() error {
|
||||
}
|
||||
|
||||
next.Unlock()
|
||||
if c.MatchExpectationsInOrder {
|
||||
if c.ordered {
|
||||
return fmt.Errorf("call to commit transaction, was not expected, next expectation is: %s", next)
|
||||
}
|
||||
}
|
||||
@ -409,7 +431,7 @@ func (c *Sqlmock) Commit() error {
|
||||
}
|
||||
|
||||
// Rollback meets http://golang.org/pkg/database/sql/driver/#Tx
|
||||
func (c *Sqlmock) Rollback() error {
|
||||
func (c *sqlmock) Rollback() error {
|
||||
var expected *ExpectedRollback
|
||||
var fulfilled int
|
||||
var ok bool
|
||||
@ -426,7 +448,7 @@ func (c *Sqlmock) Rollback() error {
|
||||
}
|
||||
|
||||
next.Unlock()
|
||||
if c.MatchExpectationsInOrder {
|
||||
if c.ordered {
|
||||
return fmt.Errorf("call to rollback transaction, was not expected, next expectation is: %s", next)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user