Open shaunc opened 4 years ago
Hi, it requires a ValueConverter registered through the sqlmock.Option. if the driver you use provides those ValueConverters, you should just register them. Otherwise you may need to copy them from the source code. As far as I've heard it works fine, is just the arrays are not the standard values in go standard database driver
@shaunc I add the same challenge to convert my array of strings into psql array. I used pq.Array
from "github.com/lib/pq"
against the value of a row I wanted sqlmock to return on a select statement. Hope this can be helpful
@shaunc, +1 to @guillermo-menjivar, I got inspired by his comment above, but I did slightly differently. Since I don't wish to introduce a whole new package into my project just for this. I wrote a function to convert my []string into something like following
stringForQuery := "{\"firstString\",\"secondString\"}"
Now both my Postgres and Sqlmock are working.
Using a ValueConverter
did the trick just as @l3pp4rd suggested. This is the working code, assuming you are using pq.StringArray(…)
in your code:
// StringArrayConverter is a database/sql driver.ValueConverter implementation
// that is used in our unit tests to teach sqlmock about the pq.StringArray type.
type StringArrayConverter struct{}
// ConvertValue converts a value to a driver Value.
func (s StringArrayConverter) ConvertValue(v any) (driver.Value, error) {
switch x := v.(type) {
case pq.StringArray:
return []string(x), nil
default:
return x, nil
}
}
func TestRepository(t *testing.T) {
db, mock, err := sqlmock.New(sqlmock.ValueConverterOption(new(StringArrayConverter)))
…
}
@fgrosse Your suggestions doesn't seems to be working.
rows := sqlmock.NewRows([]string{"ns_tenant_id", "role_id", "rbac_version", "obfuscation_fields", "users_scope", "case_sensitive_groups", "groups_scope_exclude", "groups_scope", "app_instance_scope", "ou_scope", "scope_query", "insertion_timestamp"}).
AddRow(1, 1, "v1", pq.StringArray{"field1", "field2"}, pq.StringArray{"user1", "user2"}, 0, 0, pq.StringArray{"group1", "group2"}, pq.StringArray{"app1", "app2"}, pq.StringArray{"ou1", "ou2"}, "query", "2023-08-07T00:00:00Z")
query := fmt.Sprintf("SELECT (.+) FROM .table1 WHERE ns_tenant_id = %d", test.nsTenantID)
mock.ExpectQuery(query).WillReturnRows(rows)
the error is *fmt.wrapError(&fmt.wrapError{msg:"sql: Scan error on column index 3, name \"obfuscation_fields\": unsupported Scan, storing driver.Value type string into type *[]string", err:(*errors.errorString)(0x14000298ec0)})
Is this the correct way to mock?
My code uses pg.Array to read a
text[]
field. Can I use this package to test this code? ... if so, how?Thanks!