package sql import ( "database/sql" "reflect" "testing" "github.com/stretchr/testify/require" ) func TestScanSlice(t *testing.T) { rows := &mockRows{ columns: []string{"name"}, values: [][]interface{}{{"foo"}, {"bar"}}, } var v0 []string require.NoError(t, ScanSlice(rows, &v0)) require.Equal(t, []string{"foo", "bar"}, v0) rows = &mockRows{ columns: []string{"age"}, values: [][]interface{}{{1}, {2}}, } var v1 []int require.NoError(t, ScanSlice(rows, &v1)) require.Equal(t, []int{1, 2}, v1) rows = &mockRows{ columns: []string{"name", "COUNT(*)"}, values: [][]interface{}{{"foo", 1}, {"bar", 2}}, } var v2 []struct { Name string Count int } require.NoError(t, ScanSlice(rows, &v2)) require.Equal(t, "foo", v2[0].Name) require.Equal(t, "bar", v2[1].Name) require.Equal(t, 1, v2[0].Count) require.Equal(t, 2, v2[1].Count) rows = &mockRows{ columns: []string{"nick_name", "COUNT(*)"}, values: [][]interface{}{{"foo", 1}, {"bar", 2}}, } var v3 []struct { Count int Name string `json:"nick_name"` } require.NoError(t, ScanSlice(rows, &v3)) require.Equal(t, "foo", v3[0].Name) require.Equal(t, "bar", v3[1].Name) require.Equal(t, 1, v3[0].Count) require.Equal(t, 2, v3[1].Count) rows = &mockRows{ columns: []string{"nick_name", "COUNT(*)"}, values: [][]interface{}{{"foo", 1}, {"bar", 2}}, } var v4 []*struct { Count int Name string `json:"nick_name"` Ignored string `json:"string"` } require.NoError(t, ScanSlice(rows, &v4)) require.Equal(t, "foo", v4[0].Name) require.Equal(t, "bar", v4[1].Name) require.Equal(t, 1, v4[0].Count) require.Equal(t, 2, v4[1].Count) } type mockRows struct { columns []string values [][]interface{} } func (m mockRows) Columns() ([]string, error) { return m.columns, nil } func (m mockRows) Next() bool { return len(m.values) > 0 } func (m *mockRows) Scan(vs ...interface{}) error { if len(m.values) == 0 { return sql.ErrNoRows } row := m.values[0] m.values = m.values[1:] for i := range vs { reflect.Indirect(reflect.ValueOf(vs[i])).Set(reflect.ValueOf(row[i])) } return nil }