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

Rows interface to allow building rows in different ways

This commit is contained in:
gedi 2014-02-14 00:14:32 +02:00
parent 008d8847b2
commit bdba0bb0c6
4 changed files with 80 additions and 16 deletions

View File

@ -165,7 +165,7 @@ func TestShouldNotCancelOrderWithNonPendingStatus(t *testing.T) {
// expect query to fetch order and user, match it with regexp // expect query to fetch order and user, match it with regexp
sqlmock.ExpectQuery("SELECT (.+) FROM orders AS o INNER JOIN users AS u (.+) FOR UPDATE"). sqlmock.ExpectQuery("SELECT (.+) FROM orders AS o INNER JOIN users AS u (.+) FOR UPDATE").
WithArgs(1). WithArgs(1).
WillReturnRows(sqlmock.RowsFromCSVString(columns, "1,1")) WillReturnRows(sqlmock.NewRows(columns).FromCSVString("1,1"))
// expect transaction rollback, since order status is "cancelled" // expect transaction rollback, since order status is "cancelled"
sqlmock.ExpectRollback() sqlmock.ExpectRollback()
@ -195,7 +195,7 @@ func TestShouldRefundUserWhenOrderIsCancelled(t *testing.T) {
// expect query to fetch order and user, match it with regexp // expect query to fetch order and user, match it with regexp
sqlmock.ExpectQuery("SELECT (.+) FROM orders AS o INNER JOIN users AS u (.+) FOR UPDATE"). sqlmock.ExpectQuery("SELECT (.+) FROM orders AS o INNER JOIN users AS u (.+) FOR UPDATE").
WithArgs(1). WithArgs(1).
WillReturnRows(sqlmock.RowsFromCSVString(columns, "1,0,25.75,3.25,2,10.00")) WillReturnRows(sqlmock.NewRows(columns).AddRow(1, 0, 25.75, 3.25, 2, 10.00))
// expect user balance update // expect user balance update
sqlmock.ExpectExec("UPDATE users SET balance"). sqlmock.ExpectExec("UPDATE users SET balance").
WithArgs(25.75 + 3.25, 2). // refund amount, user id WithArgs(25.75 + 3.25, 2). // refund amount, user id
@ -276,14 +276,36 @@ Instead of result we can return error..
``` go ``` go
sqlmock.ExpectQuery("SELECT (.*) FROM orders"). sqlmock.ExpectQuery("SELECT (.*) FROM orders").
WithArgs("string value"). WithArgs("string value").
WillReturnResult(sqlmock.NewResult(0, 1)) WillReturnResult(sqlmock.NewResult(0, 1))
``` ```
**WithArgs** expectation, compares values based on their type, for usual values like **string, float, int** **WithArgs** expectation, compares values based on their type, for usual values like **string, float, int**
it matches the actual value. Types like **time** are compared only by type. Other types might require different ways it matches the actual value. Types like **time** are compared only by type. Other types might require different ways
to compare them correctly, this may be improved. to compare them correctly, this may be improved.
You can build rows either from CSV string or from interface values:
**Rows** interface, which satisfies sql driver.Rows:
``` go
type Rows interface {
AddRow(...driver.Value) Rows
FromCSVString(s string) Rows
Next([]driver.Value) error
Columns() []string
Close() error
}
```
Example for to build rows:
``` go
rs := sqlmock.NewRows([]string{"column1", "column2"}).
FromCSVString("one,1\ntwo,2").
AddRow("three", 3)
```
## Run tests ## Run tests
go test go test
@ -296,6 +318,13 @@ Visit [godoc](http://godoc.org/github.com/DATA-DOG/go-sqlmock)
- handle argument comparison more efficiently - handle argument comparison more efficiently
## Changes
- **2014-02-14** RowsFromCSVString is now a part of Rows interface named as FromCSVString.
It has changed to allow more ways to construct rows and to easily extend this API in future.
See [issue 1](https://github.com/DATA-DOG/go-sqlmock/issues/1)
**RowsFromCSVString** is deprecated and will be removed in future
## Contributions ## Contributions
Feel free to open a pull request. Note, if you wish to contribute an extension to public (exported methods or types) - Feel free to open a pull request. Note, if you wish to contribute an extension to public (exported methods or types) -

49
rows.go
View File

@ -7,6 +7,16 @@ import (
"strings" "strings"
) )
// Rows interface allows to construct rows
// which also satisfies database/sql/driver.Rows interface
type Rows interface {
AddRow(...driver.Value) Rows
FromCSVString(s string) Rows
Next([]driver.Value) error
Columns() []string
Close() error
}
// a struct which implements database/sql/driver.Rows // a struct which implements database/sql/driver.Rows
type rows struct { type rows struct {
cols []string cols []string
@ -40,7 +50,17 @@ func (r *rows) Next(dest []driver.Value) error {
return nil return nil
} }
func (r *rows) AddRow(values ...interface{}) { // NewRows allows Rows to be created from a group of
// sql driver.Value or from the CSV string and
// to be used as sql driver.Rows
func NewRows(columns []string) Rows {
return &rows{cols: columns}
}
// AddRow adds a row which is built from arguments
// in the same column order, returns sql driver.Rows
// compatible interface
func (r *rows) AddRow(values ...driver.Value) Rows {
if len(values) != len(r.cols) { if len(values) != len(r.cols) {
panic("Expected number of values to match number of columns") panic("Expected number of values to match number of columns")
} }
@ -51,18 +71,33 @@ func (r *rows) AddRow(values ...interface{}) {
} }
r.rows = append(r.rows, row) r.rows = append(r.rows, row)
return r
} }
// NewRows allows Rows to be created manually to use // FromCSVString adds rows from CSV string.
// any of the types sql/driver.Value supports // Returns sql driver.Rows compatible interface
func NewRows(columns []string) *rows { func (r *rows) FromCSVString(s string) Rows {
rs := &rows{} res := strings.NewReader(strings.TrimSpace(s))
rs.cols = columns csvReader := csv.NewReader(res)
return rs
for {
res, err := csvReader.Read()
if err != nil || res == nil {
break
}
row := make([]driver.Value, len(r.cols))
for i, v := range res {
row[i] = []byte(strings.TrimSpace(v))
}
r.rows = append(r.rows, row)
}
return r
} }
// RowsFromCSVString creates Rows from CSV string // RowsFromCSVString creates Rows from CSV string
// to be used for mocked queries. Returns sql driver Rows interface // to be used for mocked queries. Returns sql driver Rows interface
// ** DEPRECATED ** will be removed in the future, use Rows.FromCSVString
func RowsFromCSVString(columns []string, s string) driver.Rows { func RowsFromCSVString(columns []string, s string) driver.Rows {
rs := &rows{} rs := &rows{}
rs.cols = columns rs.cols = columns

View File

@ -33,7 +33,7 @@ to work with:
// expect query to fetch order, match it with regexp // expect query to fetch order, match it with regexp
sqlmock.ExpectQuery("SELECT (.+) FROM orders (.+) FOR UPDATE"). sqlmock.ExpectQuery("SELECT (.+) FROM orders (.+) FOR UPDATE").
WithArgs(1). WithArgs(1).
WillReturnRows(sqlmock.RowsFromCSVString(columns, "1,1")) WillReturnRows(sqlmock.NewRows(columns).FromCSVString("1,1"))
// expect transaction rollback, since order status is "cancelled" // expect transaction rollback, since order status is "cancelled"
sqlmock.ExpectRollback() sqlmock.ExpectRollback()

View File

@ -13,7 +13,7 @@ func TestMockQuery(t *testing.T) {
t.Errorf("an error '%s' was not expected when opening a stub database connection", err) t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
} }
rs := RowsFromCSVString([]string{"id", "title"}, "5,hello world") rs := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
WithArgs(5). WithArgs(5).
@ -153,12 +153,12 @@ func TestPreparedQueryExecutions(t *testing.T) {
t.Errorf("an error '%s' was not expected when opening a stub database connection", err) t.Errorf("an error '%s' was not expected when opening a stub database connection", err)
} }
rs1 := RowsFromCSVString([]string{"id", "title"}, "5,hello world") rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
WithArgs(5). WithArgs(5).
WillReturnRows(rs1) WillReturnRows(rs1)
rs2 := RowsFromCSVString([]string{"id", "title"}, "2,whoop") rs2 := NewRows([]string{"id", "title"}).FromCSVString("2,whoop")
ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
WithArgs(2). WithArgs(2).
WillReturnRows(rs2) WillReturnRows(rs2)
@ -237,7 +237,7 @@ func TestWrongExpectations(t *testing.T) {
ExpectBegin() ExpectBegin()
rs1 := RowsFromCSVString([]string{"id", "title"}, "5,hello world") rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
ExpectQuery("SELECT (.+) FROM articles WHERE id = ?"). ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
WithArgs(5). WithArgs(5).
WillReturnRows(rs1) WillReturnRows(rs1)