diff --git a/expectations_go18.go b/expectations_go18.go index 2d5ccba..6ee8adf 100644 --- a/expectations_go18.go +++ b/expectations_go18.go @@ -4,7 +4,6 @@ package sqlmock import ( "database/sql" - "database/sql/driver" "fmt" "reflect" ) @@ -54,10 +53,6 @@ func (e *queryBasedExpectation) argsMatches(args []namedValue) error { return fmt.Errorf("could not convert %d argument %T - %+v to driver value: %s", k, e.args[k], e.args[k], err) } - if !driver.IsValue(darg) { - return fmt.Errorf("argument %d: non-subset type %T returned from Value", k, darg) - } - if !reflect.DeepEqual(darg, v.Value) { return fmt.Errorf("argument %d expected [%T - %+v] does not match actual [%T - %+v]", k, darg, darg, v.Value, v.Value) } diff --git a/expectations_go19_test.go b/expectations_go19_test.go new file mode 100644 index 0000000..4ea5f04 --- /dev/null +++ b/expectations_go19_test.go @@ -0,0 +1,43 @@ +// +build go1.9 + +package sqlmock + +import ( + "context" + "testing" +) + +func TestCustomValueConverterExec(t *testing.T) { + db, mock, _ := New(ValueConverterOption(CustomConverter{})) + expectedQuery := "INSERT INTO tags \\(name,email,age,hobbies\\) VALUES \\(\\?,\\?,\\?,\\?\\)" + query := "INSERT INTO tags (name,email,age,hobbies) VALUES (?,?,?,?)" + name := "John" + email := "j@jj.j" + age := 12 + hobbies := []string{"soccer", "netflix"} + mock.ExpectBegin() + mock.ExpectPrepare(expectedQuery) + mock.ExpectExec(expectedQuery).WithArgs(name, email, age, hobbies).WillReturnResult(NewResult(1, 1)) + mock.ExpectCommit() + + ctx := context.Background() + tx, e := db.BeginTx(ctx, nil) + if e != nil { + t.Error(e) + return + } + stmt, e := db.PrepareContext(ctx, query) + if e != nil { + t.Error(e) + return + } + _, e = stmt.Exec(name, email, age, hobbies) + if e != nil { + t.Error(e) + return + } + tx.Commit() + if err := mock.ExpectationsWereMet(); err != nil { + t.Error(err) + } +} diff --git a/expectations_test.go b/expectations_test.go index 8d2f6d7..c6889c3 100644 --- a/expectations_test.go +++ b/expectations_test.go @@ -2,7 +2,9 @@ package sqlmock import ( "database/sql/driver" + "errors" "fmt" + "reflect" "testing" "time" ) @@ -137,3 +139,57 @@ func TestBuildQuery(t *testing.T) { t.Error(err) } } + +type CustomConverter struct{} + +func (s CustomConverter) ConvertValue(v interface{}) (driver.Value, error) { + switch v.(type) { + case string: + return v.(string), nil + case []string: + return v.([]string), nil + case int: + return v.(int), nil + default: + return nil, errors.New(fmt.Sprintf("cannot convert %T with value %v", v, v)) + } +} +func TestCustomValueConverterQueryScan(t *testing.T) { + db, mock, _ := New(ValueConverterOption(CustomConverter{})) + query := ` + SELECT + name, + email, + address, + anotherfield + FROM user + where + name = 'John' + and + address = 'Jakarta' + + ` + expectedStringValue := "ValueOne" + expectedIntValue := 2 + expectedArrayValue := []string{"Three", "Four"} + mock.ExpectQuery(query).WillReturnRows(mock.NewRows([]string{"One", "Two", "Three"}).AddRow(expectedStringValue, expectedIntValue, []string{"Three", "Four"})) + row := db.QueryRow(query) + var stringValue string + var intValue int + var arrayValue []string + if e := row.Scan(&stringValue, &intValue, &arrayValue); e != nil { + t.Error(e) + } + if stringValue != expectedStringValue { + t.Errorf("Expectation %s does not met: %s", expectedStringValue, stringValue) + } + if intValue != expectedIntValue { + t.Errorf("Expectation %d does not met: %d", expectedIntValue, intValue) + } + if !reflect.DeepEqual(expectedArrayValue, arrayValue) { + t.Errorf("Expectation %v does not met: %v", expectedArrayValue, arrayValue) + } + if err := mock.ExpectationsWereMet(); err != nil { + t.Error(err) + } +}