-
-
Notifications
You must be signed in to change notification settings - Fork 409
Open
Description
I have a query that I run that has a few sql.Out
parameters. Using go-sqlmock, it doesn't appear to be possible to have values injected into the Dest
field of a sql.Out
parameter when the query is executed.
#174 added some functionality to make some sql.Out testing possible, but it doesn't appear to be possible to fully test these types of queries.
For example, here is my query I have in my code:
func (r mgRepo) ExecuteQuery(ctx context.Context, area model.Area, cluster string, requestCount int64) (*MyGlobalData, error) {
var AvailableRangeStart int64
var IDBlockSize int64
_, err := r.db.QueryContext(
ctx,
r.sProc,
sql.Named("TableName", area.String()),
sql.Named("MinBlockSize", requestCount),
sql.Named("AvailableRangeStart", sql.Out{Dest: &AvailableRangeStart}),
sql.Named("IDBlockSize", sql.Out{Dest: &IDBlockSize}),
sql.Named("RequestingServer", cluster),
)
if err != nil {
return nil, err
}
if AvailableRangeStart == 0 || IDBlockSize == 0 {
return nil, errors.New("failed to retrieve block")
}
return &MyGlobalData{
RangeStart: AvailableRangeStart,
RangeEnd: AvailableRangeStart + IDBlockSize - 1,
}, nil
}
This function validates that the AvailableRangeStart
and IDBlockSize
sql.Out parameters have been assigned (checks that they don't have the default value of 0), which means I can't run this function using a mock database without the errors.New("failed to retrieve block")
error being returned.
Here is my test:
type CustomConverter struct{}
func (s CustomConverter) ConvertValue(v interface{}) (driver.Value, error) {
if val, ok1 := v.(driver.NamedValue); ok1 {
return val.Value, nil
}
if val, ok := v.(sql.Out); ok {
res := val.Dest.(*int64)
return *res, nil
}
return v, nil
}
func TestMgRepo_ExecuteQuery(t *testing.T) {
converter := sqlmock.ValueConverterOption(CustomConverter{})
db, mock, err := sqlmock.New(converter)
if err != nil {
t.Errorf("failed to create sql mock")
}
a := int64(100)
i := int64(10)
mock.ExpectQuery("test").WithArgs(
sql.Named("TableName", "Contact_log"),
sql.Named("MinBlockSize", int64(10)),
sql.Named("AvailableRangeStart", sql.Out{Dest: &a}),
sql.Named("IDBlockSize", sql.Out{Dest: &i}),
sql.Named("RequestingServer", "test"),
).WillReturnRows(nil)
mgRepo := mgRepo{
db: db,
sProc: "test",
}
_, err = mgRepo.ExecuteQuery(context.Background(), model.Contact_log, "test", int64(10))
assert.Nil(t, err)
}
Here is the test execution output:
=== RUN TestMgRepo_ExecuteQuery
--- FAIL: TestMgRepo_ExecuteQuery (0.00s)
myGlobal_test.go:164:
Error Trace: myGlobal_test.go:164
Error: Expected nil, but got: &errors.errorString{s:"Query 'test', arguments do not match: argument 2 expected [int64 - 100] does not match actual [int64 - 0]"}
Test: TestMgRepo_ExecuteQuery
FAIL
maxiancillotti, Sunyue and agriffin1-godaddy
Metadata
Metadata
Assignees
Labels
No labels