1
0
mirror of https://github.com/DATA-DOG/go-sqlmock.git synced 2025-03-23 21:09:19 +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

@ -165,7 +165,7 @@ func TestShouldNotCancelOrderWithNonPendingStatus(t *testing.T) {
// 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").
WithArgs(1).
WillReturnRows(sqlmock.RowsFromCSVString(columns, "1,1"))
WillReturnRows(sqlmock.NewRows(columns).FromCSVString("1,1"))
// expect transaction rollback, since order status is "cancelled"
sqlmock.ExpectRollback()
@ -195,7 +195,7 @@ func TestShouldRefundUserWhenOrderIsCancelled(t *testing.T) {
// 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").
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
sqlmock.ExpectExec("UPDATE users SET balance").
WithArgs(25.75 + 3.25, 2). // refund amount, user id
@ -276,14 +276,36 @@ Instead of result we can return error..
``` go
sqlmock.ExpectQuery("SELECT (.*) FROM orders").
WithArgs("string value").
WillReturnResult(sqlmock.NewResult(0, 1))
WithArgs("string value").
WillReturnResult(sqlmock.NewResult(0, 1))
```
**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
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
go test
@ -296,6 +318,13 @@ Visit [godoc](http://godoc.org/github.com/DATA-DOG/go-sqlmock)
- 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
Feel free to open a pull request. Note, if you wish to contribute an extension to public (exported methods or types) -

49
rows.go

@ -7,6 +7,16 @@ import (
"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
type rows struct {
cols []string
@ -40,7 +50,17 @@ func (r *rows) Next(dest []driver.Value) error {
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) {
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)
return r
}
// NewRows allows Rows to be created manually to use
// any of the types sql/driver.Value supports
func NewRows(columns []string) *rows {
rs := &rows{}
rs.cols = columns
return rs
// FromCSVString adds rows from CSV string.
// Returns sql driver.Rows compatible interface
func (r *rows) FromCSVString(s string) Rows {
res := strings.NewReader(strings.TrimSpace(s))
csvReader := csv.NewReader(res)
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
// 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 {
rs := &rows{}
rs.cols = columns

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

@ -13,7 +13,7 @@ func TestMockQuery(t *testing.T) {
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 = ?").
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)
}
rs1 := RowsFromCSVString([]string{"id", "title"}, "5,hello world")
rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
WithArgs(5).
WillReturnRows(rs1)
rs2 := RowsFromCSVString([]string{"id", "title"}, "2,whoop")
rs2 := NewRows([]string{"id", "title"}).FromCSVString("2,whoop")
ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
WithArgs(2).
WillReturnRows(rs2)
@ -237,7 +237,7 @@ func TestWrongExpectations(t *testing.T) {
ExpectBegin()
rs1 := RowsFromCSVString([]string{"id", "title"}, "5,hello world")
rs1 := NewRows([]string{"id", "title"}).FromCSVString("5,hello world")
ExpectQuery("SELECT (.+) FROM articles WHERE id = ?").
WithArgs(5).
WillReturnRows(rs1)