1
0
mirror of https://github.com/DATA-DOG/go-sqlmock.git synced 2025-03-31 21:45:15 +02:00

rows scan error mocking test

This commit is contained in:
gedi 2015-08-05 13:37:58 +03:00
parent acfbd5d998
commit 5a740a6373
3 changed files with 21 additions and 13 deletions

11
rows.go
View File

@ -8,7 +8,8 @@ import (
) )
// CSVColumnParser is a function which converts trimmed csv // CSVColumnParser is a function which converts trimmed csv
// column string to a []byte representation. // column string to a []byte representation. currently
// transforms NULL to nil
var CSVColumnParser = func(s string) []byte { var CSVColumnParser = func(s string) []byte {
switch { switch {
case strings.ToLower(s) == "null": case strings.ToLower(s) == "null":
@ -54,7 +55,7 @@ type rows struct {
cols []string cols []string
rows [][]driver.Value rows [][]driver.Value
pos int pos int
scanErr map[int]error nextErr map[int]error
closeErr error closeErr error
} }
@ -77,14 +78,14 @@ func (r *rows) Next(dest []driver.Value) error {
dest[i] = col dest[i] = col
} }
return r.scanErr[r.pos-1] return r.nextErr[r.pos-1]
} }
// NewRows allows Rows to be created from a // NewRows allows Rows to be created from a
// sql driver.Value slice or from the CSV string and // sql driver.Value slice or from the CSV string and
// to be used as sql driver.Rows // to be used as sql driver.Rows
func NewRows(columns []string) Rows { func NewRows(columns []string) Rows {
return &rows{cols: columns, scanErr: make(map[int]error)} return &rows{cols: columns, nextErr: make(map[int]error)}
} }
func (r *rows) CloseError(err error) Rows { func (r *rows) CloseError(err error) Rows {
@ -93,7 +94,7 @@ func (r *rows) CloseError(err error) Rows {
} }
func (r *rows) RowError(row int, err error) Rows { func (r *rows) RowError(row int, err error) Rows {
r.scanErr[row] = err r.nextErr[row] = err
return r return r
} }

View File

@ -180,10 +180,7 @@ func TestQuerySingleRow(t *testing.T) {
} }
} }
// @TODO: the only way to mock columns error would be func TestRowsScanError(t *testing.T) {
// to return nil instead of rows, but rows.Close will
// panic due to a bug in go sql package
func TODO_TestRowsColumnsError(t *testing.T) {
t.Parallel() t.Parallel()
db, mock, err := New() db, mock, err := New()
if err != nil { if err != nil {
@ -191,16 +188,27 @@ func TODO_TestRowsColumnsError(t *testing.T) {
} }
defer db.Close() defer db.Close()
mock.ExpectQuery("SELECT").WillReturnRows(nil) r := NewRows([]string{"col1", "col2"}).AddRow("one", "two").AddRow("one", nil)
mock.ExpectQuery("SELECT").WillReturnRows(r)
rs, err := db.Query("SELECT") rs, err := db.Query("SELECT")
if err != nil { if err != nil {
t.Fatalf("unexpected error: %s", err) t.Fatalf("unexpected error: %s", err)
} }
defer rs.Close()
_, err = rs.Columns() var one, two string
if !rs.Next() || rs.Err() != nil || rs.Scan(&one, &two) != nil {
t.Fatal("unexpected error on first row scan")
}
if !rs.Next() || rs.Err() != nil {
t.Fatal("unexpected error on second row read")
}
err = rs.Scan(&one, &two)
if err == nil { if err == nil {
t.Fatal("expected an error for columns") t.Fatal("expected an error for scan, but got none")
} }
if err := mock.ExpectationsWereMet(); err != nil { if err := mock.ExpectationsWereMet(); err != nil {

View File

@ -201,7 +201,6 @@ func (c *Sqlmock) Query(query string, args []driver.Value) (rw driver.Rows, err
return nil, t.err // mocked to return error return nil, t.err // mocked to return error
} }
// remove when rows_test.go:186 is available, won't cause a BC
if t.rows == nil { if t.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, t, t) 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, t, t)
} }