You've already forked go-sqlmock
							
							
				mirror of
				https://github.com/DATA-DOG/go-sqlmock.git
				synced 2025-10-30 23:47:46 +02:00 
			
		
		
		
	return error instead panic if argument reflection types are not matching
This commit is contained in:
		| @@ -323,12 +323,9 @@ rs := sqlmock.NewRows([]string{"column1", "column2"}). | ||||
|  | ||||
| Visit [godoc](http://godoc.org/github.com/DATA-DOG/go-sqlmock) | ||||
|  | ||||
| ## TODO | ||||
|  | ||||
| - handle argument comparison more efficiently | ||||
|  | ||||
| ## Changes | ||||
|  | ||||
| - **2014-08-16** instead of **panic** during reflect type mismatch when comparing query arguments - now return error | ||||
| - **2014-08-14** added **sqlmock.NewErrorResult** which gives an option to return driver.Result with errors for | ||||
| interface methods, see [issue](https://github.com/DATA-DOG/go-sqlmock/issues/5) | ||||
| - **2014-05-29** allow to match arguments in more sophisticated ways, by providing an **sqlmock.Argument** interface | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package sqlmock | ||||
| import ( | ||||
| 	"database/sql/driver" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| ) | ||||
|  | ||||
| type conn struct { | ||||
| @@ -49,7 +50,7 @@ func (c *conn) next() (e expectation) { | ||||
| 	return nil // all expectations were fulfilled | ||||
| } | ||||
|  | ||||
| func (c *conn) Exec(query string, args []driver.Value) (driver.Result, error) { | ||||
| func (c *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) { | ||||
| 	e := c.next() | ||||
| 	query = stripQuery(query) | ||||
| 	if e == nil { | ||||
| @@ -70,6 +71,8 @@ func (c *conn) Exec(query string, args []driver.Value) (driver.Result, error) { | ||||
| 		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 | ||||
|  | ||||
| 	if !eq.queryMatches(query) { | ||||
| 		return nil, fmt.Errorf("exec query '%s', does not match regex '%s'", query, eq.sqlRegex.String()) | ||||
| 	} | ||||
| @@ -78,14 +81,14 @@ func (c *conn) Exec(query string, args []driver.Value) (driver.Result, error) { | ||||
| 		return nil, fmt.Errorf("exec query '%s', args %+v does not match expected %+v", query, args, eq.args) | ||||
| 	} | ||||
|  | ||||
| 	return eq.result, nil | ||||
| 	return eq.result, err | ||||
| } | ||||
|  | ||||
| func (c *conn) Prepare(query string) (driver.Stmt, error) { | ||||
| 	return &statement{mock.conn, stripQuery(query)}, nil | ||||
| } | ||||
|  | ||||
| func (c *conn) Query(query string, args []driver.Value) (driver.Rows, error) { | ||||
| func (c *conn) Query(query string, args []driver.Value) (rw driver.Rows, err error) { | ||||
| 	e := c.next() | ||||
| 	query = stripQuery(query) | ||||
| 	if e == nil { | ||||
| @@ -106,6 +109,8 @@ func (c *conn) Query(query string, args []driver.Value) (driver.Rows, error) { | ||||
| 		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 | ||||
|  | ||||
| 	if !eq.queryMatches(query) { | ||||
| 		return nil, fmt.Errorf("query '%s', does not match regex [%s]", query, eq.sqlRegex.String()) | ||||
| 	} | ||||
| @@ -114,5 +119,15 @@ func (c *conn) Query(query string, args []driver.Value) (driver.Rows, error) { | ||||
| 		return nil, fmt.Errorf("query '%s', args %+v does not match expected %+v", query, args, eq.args) | ||||
| 	} | ||||
|  | ||||
| 	return eq.rows, nil | ||||
| 	return eq.rows, err | ||||
| } | ||||
|  | ||||
| func argMatcherErrorHandler(errp *error) { | ||||
| 	if e := recover(); e != nil { | ||||
| 		if se, ok := e.(*reflect.ValueError); ok { // catch reflect error, failed type conversion | ||||
| 			*errp = fmt.Errorf("Failed to compare query arguments: %s", se) | ||||
| 		} else { | ||||
| 			panic(e) // overwise panic | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -420,3 +420,19 @@ func TestRowBuilderAndNilTypes(t *testing.T) { | ||||
| 		t.Errorf("error '%s' was not expected while closing the database", err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestArgumentReflectValueTypeError(t *testing.T) { | ||||
| 	db, err := sql.Open("mock", "") | ||||
| 	if err != nil { | ||||
| 		t.Errorf("an error '%s' was not expected when opening a stub database connection", err) | ||||
| 	} | ||||
|  | ||||
| 	rs := NewRows([]string{"id"}).AddRow(1) | ||||
|  | ||||
| 	ExpectQuery("SELECT (.+) FROM sales").WithArgs(5.5).WillReturnRows(rs) | ||||
|  | ||||
| 	_, err = db.Query("SELECT * FROM sales WHERE x = ?", 5) | ||||
| 	if err == nil { | ||||
| 		t.Error("Expected error, but got none") | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user