Skip to content

Commit 9d03611

Browse files
committed
allow to expect prepared statement to be closed, closes #89
1 parent c91a7f4 commit 9d03611

File tree

5 files changed

+57
-8
lines changed

5 files changed

+57
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ It only asserts that argument is of `time.Time` type.
190190

191191
## Change Log
192192

193+
- **2017-09-01** - it is now possible to expect that prepared statement will be closed,
194+
using **ExpectedPrepare.WillBeClosed**.
193195
- **2017-02-09** - implemented support for **go1.8** features. **Rows** interface was changed to struct
194196
but contains all methods as before and should maintain backwards compatibility. **ExpectedQuery.WillReturnRows** may now
195197
accept multiple row sets.

expectations.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,13 @@ func (e *ExpectedExec) WillReturnResult(result driver.Result) *ExpectedExec {
252252
// Returned by *Sqlmock.ExpectPrepare.
253253
type ExpectedPrepare struct {
254254
commonExpectation
255-
mock *sqlmock
256-
sqlRegex *regexp.Regexp
257-
statement driver.Stmt
258-
closeErr error
259-
delay time.Duration
255+
mock *sqlmock
256+
sqlRegex *regexp.Regexp
257+
statement driver.Stmt
258+
closeErr error
259+
mustBeClosed bool
260+
wasClosed bool
261+
delay time.Duration
260262
}
261263

262264
// 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
278280
return e
279281
}
280282

283+
// WillBeClosed expects this prepared statement to
284+
// be closed.
285+
func (e *ExpectedPrepare) WillBeClosed() *ExpectedPrepare {
286+
e.mustBeClosed = true
287+
return e
288+
}
289+
281290
// ExpectQuery allows to expect Query() or QueryRow() on this prepared statement.
282291
// this method is convenient in order to prevent duplicating sql query string matching.
283292
func (e *ExpectedPrepare) ExpectQuery() *ExpectedQuery {

sqlmock.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ func (c *sqlmock) ExpectationsWereMet() error {
154154
if !e.fulfilled() {
155155
return fmt.Errorf("there is a remaining expectation which was not matched: %s", e)
156156
}
157+
158+
// for expected prepared statement check whether it was closed if expected
159+
if prep, ok := e.(*ExpectedPrepare); ok {
160+
if prep.mustBeClosed && !prep.wasClosed {
161+
return fmt.Errorf("expected prepared statement to be closed, but it was not: %s", prep)
162+
}
163+
}
157164
}
158165
return nil
159166
}
@@ -302,7 +309,7 @@ func (c *sqlmock) Prepare(query string) (driver.Stmt, error) {
302309
}
303310

304311
time.Sleep(ex.delay)
305-
return &statement{c, query, ex.closeErr}, nil
312+
return &statement{c, ex, query}, nil
306313
}
307314

308315
func (c *sqlmock) prepare(query string) (*ExpectedPrepare, error) {

sqlmock_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,3 +1033,33 @@ func TestExpectedBeginOrder(t *testing.T) {
10331033
t.Error("an error was expected when calling close, but got none")
10341034
}
10351035
}
1036+
1037+
func TestPreparedStatementCloseExpectation(t *testing.T) {
1038+
// Open new mock database
1039+
db, mock, err := New()
1040+
if err != nil {
1041+
fmt.Println("error creating mock database")
1042+
return
1043+
}
1044+
defer db.Close()
1045+
1046+
ep := mock.ExpectPrepare("INSERT INTO ORDERS").WillBeClosed()
1047+
ep.ExpectExec().WillReturnResult(NewResult(1, 1))
1048+
1049+
stmt, err := db.Prepare("INSERT INTO ORDERS(ID, STATUS) VALUES (?, ?)")
1050+
if err != nil {
1051+
t.Fatal(err)
1052+
}
1053+
1054+
if _, err := stmt.Exec(1, "Hello"); err != nil {
1055+
t.Fatal(err)
1056+
}
1057+
1058+
if err := stmt.Close(); err != nil {
1059+
t.Fatal(err)
1060+
}
1061+
1062+
if err := mock.ExpectationsWereMet(); err != nil {
1063+
t.Errorf("there were unfulfilled expections: %s", err)
1064+
}
1065+
}

statement.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import (
66

77
type statement struct {
88
conn *sqlmock
9+
ex *ExpectedPrepare
910
query string
10-
err error
1111
}
1212

1313
func (stmt *statement) Close() error {
14-
return stmt.err
14+
stmt.ex.wasClosed = true
15+
return stmt.ex.closeErr
1516
}
1617

1718
func (stmt *statement) NumInput() int {

0 commit comments

Comments
 (0)