From 02e14710b4c0d61c24f043b83b0bda485d92a0a5 Mon Sep 17 00:00:00 2001 From: Craig Jackson Date: Fri, 23 Jan 2015 16:22:41 -0700 Subject: [PATCH] Move errors in expectation to after query and args checks. --- connection.go | 30 ++-- connection_test.go | 378 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 394 insertions(+), 14 deletions(-) create mode 100644 connection_test.go diff --git a/connection.go b/connection.go index 493cf42..ed43f06 100644 --- a/connection.go +++ b/connection.go @@ -63,13 +63,6 @@ func (c *conn) Exec(query string, args []driver.Value) (res driver.Result, err e } eq.triggered = true - if eq.err != nil { - return nil, eq.err // mocked to return error - } - - if eq.result == nil { - return nil, fmt.Errorf("exec query '%s' with args %+v, must return a database/sql/driver.result, but it was not set for expectation %T as %+v", query, args, eq, eq) - } defer argMatcherErrorHandler(&err) // converts panic to error in case of reflect value type mismatch @@ -81,6 +74,14 @@ func (c *conn) Exec(query string, args []driver.Value) (res driver.Result, err e return nil, fmt.Errorf("exec query '%s', args %+v does not match expected %+v", query, args, eq.args) } + if eq.err != nil { + return nil, eq.err // mocked to return error + } + + if eq.result == nil { + return nil, fmt.Errorf("exec query '%s' with args %+v, must return a database/sql/driver.result, but it was not set for expectation %T as %+v", query, args, eq, eq) + } + return eq.result, err } @@ -117,13 +118,6 @@ func (c *conn) Query(query string, args []driver.Value) (rw driver.Rows, err err } eq.triggered = true - if eq.err != nil { - return nil, eq.err // mocked to return error - } - - if eq.rows == nil { - return nil, fmt.Errorf("query '%s' with args %+v, must return a database/sql/driver.rows, but it was not set for expectation %T as %+v", query, args, eq, eq) - } defer argMatcherErrorHandler(&err) // converts panic to error in case of reflect value type mismatch @@ -135,6 +129,14 @@ func (c *conn) Query(query string, args []driver.Value) (rw driver.Rows, err err return nil, fmt.Errorf("query '%s', args %+v does not match expected %+v", query, args, eq.args) } + if eq.err != nil { + return nil, eq.err // mocked to return error + } + + if eq.rows == nil { + return nil, fmt.Errorf("query '%s' with args %+v, must return a database/sql/driver.rows, but it was not set for expectation %T as %+v", query, args, eq, eq) + } + return eq.rows, err } diff --git a/connection_test.go b/connection_test.go new file mode 100644 index 0000000..b4aabe9 --- /dev/null +++ b/connection_test.go @@ -0,0 +1,378 @@ +package sqlmock + +import ( + "database/sql/driver" + "errors" + "regexp" + "testing" +) + +func TestExecNoExpectations(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedExec{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + triggered: true, + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("otherquery")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Exec("query", []driver.Value{123}) + if res != nil { + t.Error("Result should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("all expectations were already fulfilled, call to exec")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestExecExpectationMismatch(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedQuery{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("otherquery")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Exec("query", []driver.Value{123}) + if res != nil { + t.Error("Result should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("was not expected, next expectation is")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestExecQueryMismatch(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedExec{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("otherquery")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Exec("query", []driver.Value{123}) + if res != nil { + t.Error("Result should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("does not match regex")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestExecArgsMismatch(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedExec{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Exec("query", []driver.Value{123}) + if res != nil { + t.Error("Result should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("does not match expected")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestExecWillReturnError(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedExec{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + }, + }, + }, + } + res, err := c.Exec("query", []driver.Value{123}) + if res != nil { + t.Error("Result should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + if err.Error() != "WillReturnError" { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestExecMissingResult(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedExec{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{}, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + args: []driver.Value{123}, + }, + }, + }, + } + res, err := c.Exec("query", []driver.Value{123}) + if res != nil { + t.Error("Result should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("must return a database/sql/driver.result, but it was not set for expectation")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestExec(t *testing.T) { + expectedResult := driver.Result(&result{}) + c := &conn{ + expectations: []expectation{ + &expectedExec{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{}, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + args: []driver.Value{123}, + }, + result: expectedResult, + }, + }, + } + res, err := c.Exec("query", []driver.Value{123}) + if res == nil { + t.Error("Result should not be nil") + } + if res != expectedResult { + t.Errorf("Result should match expected Result (actual %+v)", res) + } + if err != nil { + t.Errorf("error should be nil (actual %s)", err.Error()) + } +} + +func TestQueryNoExpectations(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedQuery{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + triggered: true, + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("otherquery")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Query("query", []driver.Value{123}) + if res != nil { + t.Error("Rows should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("all expectations were already fulfilled, call to query")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestQueryExpectationMismatch(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedExec{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("otherquery")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Query("query", []driver.Value{123}) + if res != nil { + t.Error("Rows should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("was not expected, next expectation is")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestQueryQueryMismatch(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedQuery{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("otherquery")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Query("query", []driver.Value{123}) + if res != nil { + t.Error("Rows should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("does not match regex")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestQueryArgsMismatch(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedQuery{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + args: []driver.Value{456}, + }, + }, + }, + } + res, err := c.Query("query", []driver.Value{123}) + if res != nil { + t.Error("Rows should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("does not match expected")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestQueryWillReturnError(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedQuery{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{ + err: errors.New("WillReturnError"), + }, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + }, + }, + }, + } + res, err := c.Query("query", []driver.Value{123}) + if res != nil { + t.Error("Rows should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + if err.Error() != "WillReturnError" { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestQueryMissingRows(t *testing.T) { + c := &conn{ + expectations: []expectation{ + &expectedQuery{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{}, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + args: []driver.Value{123}, + }, + }, + }, + } + res, err := c.Query("query", []driver.Value{123}) + if res != nil { + t.Error("Rows should be nil") + } + if err == nil { + t.Error("error should not be nil") + } + pattern := regexp.MustCompile(regexp.QuoteMeta("must return a database/sql/driver.rows, but it was not set for expectation")) + if !pattern.MatchString(err.Error()) { + t.Errorf("error should match expected error message (actual: %s)", err.Error()) + } +} + +func TestQuery(t *testing.T) { + expectedRows := driver.Rows(&rows{}) + c := &conn{ + expectations: []expectation{ + &expectedQuery{ + queryBasedExpectation: queryBasedExpectation{ + commonExpectation: commonExpectation{}, + sqlRegex: regexp.MustCompile(regexp.QuoteMeta("query")), + args: []driver.Value{123}, + }, + rows: expectedRows, + }, + }, + } + rows, err := c.Query("query", []driver.Value{123}) + if rows == nil { + t.Error("Rows should not be nil") + } + if rows != expectedRows { + t.Errorf("Rows should match expected Rows (actual %+v)", rows) + } + if err != nil { + t.Errorf("error should be nil (actual %s)", err.Error()) + } +}