mirror of
https://github.com/DATA-DOG/go-sqlmock.git
synced 2025-02-21 19:06:45 +02:00
allow to expect prepared statement to be closed, closes #89
This commit is contained in:
parent
c91a7f4b68
commit
9d03611ad1
@ -190,6 +190,8 @@ It only asserts that argument is of `time.Time` type.
|
|||||||
|
|
||||||
## Change Log
|
## Change Log
|
||||||
|
|
||||||
|
- **2017-09-01** - it is now possible to expect that prepared statement will be closed,
|
||||||
|
using **ExpectedPrepare.WillBeClosed**.
|
||||||
- **2017-02-09** - implemented support for **go1.8** features. **Rows** interface was changed to struct
|
- **2017-02-09** - implemented support for **go1.8** features. **Rows** interface was changed to struct
|
||||||
but contains all methods as before and should maintain backwards compatibility. **ExpectedQuery.WillReturnRows** may now
|
but contains all methods as before and should maintain backwards compatibility. **ExpectedQuery.WillReturnRows** may now
|
||||||
accept multiple row sets.
|
accept multiple row sets.
|
||||||
|
@ -252,11 +252,13 @@ func (e *ExpectedExec) WillReturnResult(result driver.Result) *ExpectedExec {
|
|||||||
// Returned by *Sqlmock.ExpectPrepare.
|
// Returned by *Sqlmock.ExpectPrepare.
|
||||||
type ExpectedPrepare struct {
|
type ExpectedPrepare struct {
|
||||||
commonExpectation
|
commonExpectation
|
||||||
mock *sqlmock
|
mock *sqlmock
|
||||||
sqlRegex *regexp.Regexp
|
sqlRegex *regexp.Regexp
|
||||||
statement driver.Stmt
|
statement driver.Stmt
|
||||||
closeErr error
|
closeErr error
|
||||||
delay time.Duration
|
mustBeClosed bool
|
||||||
|
wasClosed bool
|
||||||
|
delay time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// WillReturnError allows to set an error for the expected *sql.DB.Prepare or *sql.Tx.Prepare action.
|
// WillReturnError allows to set an error for the expected *sql.DB.Prepare or *sql.Tx.Prepare action.
|
||||||
@ -278,6 +280,13 @@ func (e *ExpectedPrepare) WillDelayFor(duration time.Duration) *ExpectedPrepare
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WillBeClosed expects this prepared statement to
|
||||||
|
// be closed.
|
||||||
|
func (e *ExpectedPrepare) WillBeClosed() *ExpectedPrepare {
|
||||||
|
e.mustBeClosed = true
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// ExpectQuery allows to expect Query() or QueryRow() on this prepared statement.
|
// ExpectQuery allows to expect Query() or QueryRow() on this prepared statement.
|
||||||
// this method is convenient in order to prevent duplicating sql query string matching.
|
// this method is convenient in order to prevent duplicating sql query string matching.
|
||||||
func (e *ExpectedPrepare) ExpectQuery() *ExpectedQuery {
|
func (e *ExpectedPrepare) ExpectQuery() *ExpectedQuery {
|
||||||
|
@ -154,6 +154,13 @@ func (c *sqlmock) ExpectationsWereMet() error {
|
|||||||
if !e.fulfilled() {
|
if !e.fulfilled() {
|
||||||
return fmt.Errorf("there is a remaining expectation which was not matched: %s", e)
|
return fmt.Errorf("there is a remaining expectation which was not matched: %s", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for expected prepared statement check whether it was closed if expected
|
||||||
|
if prep, ok := e.(*ExpectedPrepare); ok {
|
||||||
|
if prep.mustBeClosed && !prep.wasClosed {
|
||||||
|
return fmt.Errorf("expected prepared statement to be closed, but it was not: %s", prep)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -302,7 +309,7 @@ func (c *sqlmock) Prepare(query string) (driver.Stmt, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(ex.delay)
|
time.Sleep(ex.delay)
|
||||||
return &statement{c, query, ex.closeErr}, nil
|
return &statement{c, ex, query}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *sqlmock) prepare(query string) (*ExpectedPrepare, error) {
|
func (c *sqlmock) prepare(query string) (*ExpectedPrepare, error) {
|
||||||
|
@ -1033,3 +1033,33 @@ func TestExpectedBeginOrder(t *testing.T) {
|
|||||||
t.Error("an error was expected when calling close, but got none")
|
t.Error("an error was expected when calling close, but got none")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPreparedStatementCloseExpectation(t *testing.T) {
|
||||||
|
// Open new mock database
|
||||||
|
db, mock, err := New()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error creating mock database")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
ep := mock.ExpectPrepare("INSERT INTO ORDERS").WillBeClosed()
|
||||||
|
ep.ExpectExec().WillReturnResult(NewResult(1, 1))
|
||||||
|
|
||||||
|
stmt, err := db.Prepare("INSERT INTO ORDERS(ID, STATUS) VALUES (?, ?)")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := stmt.Exec(1, "Hello"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stmt.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||||||
|
t.Errorf("there were unfulfilled expections: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,12 +6,13 @@ import (
|
|||||||
|
|
||||||
type statement struct {
|
type statement struct {
|
||||||
conn *sqlmock
|
conn *sqlmock
|
||||||
|
ex *ExpectedPrepare
|
||||||
query string
|
query string
|
||||||
err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stmt *statement) Close() error {
|
func (stmt *statement) Close() error {
|
||||||
return stmt.err
|
stmt.ex.wasClosed = true
|
||||||
|
return stmt.ex.closeErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stmt *statement) NumInput() int {
|
func (stmt *statement) NumInput() int {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user