Create new example test showing how to use ksql.Mock{}

pull/20/head
Vinícius Garcia 2022-04-06 18:29:28 -03:00
parent d229767d98
commit 2bf3a1a124
2 changed files with 271 additions and 19 deletions

View File

@ -11,7 +11,7 @@ import (
"github.com/vingarcia/ksql/nullable"
)
func TestCreateUser(t *testing.T) {
func TestCreateUserWithGoMock(t *testing.T) {
t.Run("should call ksql.Insert correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
@ -25,8 +25,8 @@ func TestCreateUser(t *testing.T) {
var users []interface{}
mockDB.EXPECT().Insert(gomock.Any(), gomock.Any(), gomock.Any()).
DoAndReturn(func(ctx context.Context, table ksql.Table, records ...interface{}) error {
users = append(users, records...)
DoAndReturn(func(ctx context.Context, table ksql.Table, record interface{}) error {
users = append(users, record)
return nil
})
@ -51,8 +51,7 @@ func TestCreateUser(t *testing.T) {
var users []map[string]interface{}
mockDB.EXPECT().Insert(gomock.Any(), gomock.Any(), gomock.Any()).
DoAndReturn(func(ctx context.Context, table ksql.Table, records ...interface{}) error {
for _, record := range records {
DoAndReturn(func(ctx context.Context, table ksql.Table, record interface{}) error {
// The StructToMap function will convert a struct with `ksql` tags
// into a map using the ksql attr names as keys.
//
@ -63,7 +62,7 @@ func TestCreateUser(t *testing.T) {
return err
}
users = append(users, uMap)
}
return nil
})
@ -77,7 +76,7 @@ func TestCreateUser(t *testing.T) {
})
}
func TestUpdateUserScore(t *testing.T) {
func TestUpdateUserScoreWithGoMock(t *testing.T) {
t.Run("should call ksql.QueryOne() & Patch() correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
@ -121,7 +120,7 @@ func TestUpdateUserScore(t *testing.T) {
})
}
func TestListUsers(t *testing.T) {
func TestListUsersWithGoMock(t *testing.T) {
t.Run("should call ksql.QueryOne() & Query() correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
@ -183,7 +182,7 @@ func TestListUsers(t *testing.T) {
})
}
func TestStreamAllUsers(t *testing.T) {
func TestStreamAllUsersWithGoMock(t *testing.T) {
t.Run("should call ksql.QueryChunks correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()
@ -255,7 +254,7 @@ func TestStreamAllUsers(t *testing.T) {
})
}
func TestDeleteUser(t *testing.T) {
func TestDeleteUserWithGoMock(t *testing.T) {
t.Run("should call ksql.Delete correctly", func(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()

View File

@ -0,0 +1,253 @@
package exampleservice
import (
"context"
"testing"
"github.com/ditointernet/go-assert"
"github.com/vingarcia/ksql"
"github.com/vingarcia/ksql/ksqltest"
"github.com/vingarcia/ksql/nullable"
)
func TestCreateUserWithKsqlMock(t *testing.T) {
t.Run("should call ksql.Insert correctly", func(t *testing.T) {
var users []interface{}
mockDB := ksql.Mock{
InsertFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
users = append(users, record)
return nil
},
}
s := Service{
db: mockDB,
streamChunkSize: 100,
}
user := UserEntity{Name: nullable.String("TestUser")}
err := s.CreateUser(context.TODO(), user)
assert.Equal(t, nil, err)
assert.Equal(t, 1, len(users))
assert.Equal(t, &user, users[0])
})
t.Run("another way of testing input structs", func(t *testing.T) {
var users []map[string]interface{}
mockDB := ksql.Mock{
InsertFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
// The StructToMap function will convert a struct with `ksql` tags
// into a map using the ksql attr names as keys.
//
// If you are inserting an anonymous struct (not usual) this function
// can make your tests shorter:
uMap, err := ksqltest.StructToMap(record)
if err != nil {
return err
}
users = append(users, uMap)
return nil
},
}
s := Service{
db: mockDB,
streamChunkSize: 100,
}
user := UserEntity{Name: nullable.String("TestUser")}
err := s.CreateUser(context.TODO(), user)
assert.Equal(t, nil, err)
assert.Equal(t, 1, len(users))
assert.Equal(t, "TestUser", users[0]["name"])
})
}
func TestUpdateUserScoreWithKsqlMock(t *testing.T) {
t.Run("should call ksql.QueryOne() & Patch() correctly", func(t *testing.T) {
var users []interface{}
mockDB := ksql.Mock{
QueryOneFn: func(ctx context.Context, result interface{}, query string, params ...interface{}) error {
// This function will use reflection to fill the
// struct fields with the values from the map
return ksqltest.FillStructWith(result, map[string]interface{}{
// Use int this map the keys you set on the ksql tags, e.g. `ksql:"score"`
// Each of these fields represent the database rows returned
// by the query.
"score": 42,
})
},
PatchFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
users = append(users, record)
return nil
},
}
s := Service{
db: mockDB,
streamChunkSize: 100,
}
err := s.UpdateUserScore(context.TODO(), 1, -2)
assert.Equal(t, nil, err)
assert.Equal(t, 1, len(users))
resultUser := UserEntity{
ID: 1,
Score: nullable.Int(40),
}
assert.Equal(t, &resultUser, users[0])
})
}
func TestListUsersWithKsqlMock(t *testing.T) {
t.Run("should call ksql.QueryOne() & Query() correctly", func(t *testing.T) {
mockDB := ksql.Mock{
QueryOneFn: func(ctx context.Context, result interface{}, query string, params ...interface{}) error {
// This function will use reflection to fill the
// struct fields with the values from the map
return ksqltest.FillStructWith(result, map[string]interface{}{
// Use int this map the keys you set on the ksql tags, e.g. `ksql:"score"`
// Each of these fields represent the database rows returned
// by the query.
"count": 420,
})
},
QueryFn: func(ctx context.Context, results interface{}, query string, params ...interface{}) error {
return ksqltest.FillSliceWith(results, []map[string]interface{}{
{
"id": 1,
"name": "fake name",
"age": 42,
},
{
"id": 2,
"name": "another fake name",
"age": 43,
},
})
},
}
s := Service{
db: mockDB,
streamChunkSize: 100,
}
total, users, err := s.ListUsers(context.TODO(), 40, 2)
assert.Equal(t, nil, err)
assert.Equal(t, 420, total)
assert.Equal(t, 2, len(users))
expectedUsers := []UserEntity{
{
ID: 1,
Name: nullable.String("fake name"),
Age: nullable.Int(42),
},
{
ID: 2,
Name: nullable.String("another fake name"),
Age: nullable.Int(43),
},
}
assert.Equal(t, expectedUsers, users)
})
}
func TestStreamAllUsersWithKsqlMock(t *testing.T) {
t.Run("should call ksql.QueryChunks correctly", func(t *testing.T) {
mockDB := ksql.Mock{
QueryChunksFn: func(ctx context.Context, parser ksql.ChunkParser) error {
// Chunk 1:
err := ksqltest.CallFunctionWithRows(parser.ForEachChunk, []map[string]interface{}{
{
"id": 1,
"name": "fake name",
"age": 42,
},
{
"id": 2,
"name": "another fake name",
"age": 43,
},
})
if err != nil {
return err
}
// Chunk 2:
err = ksqltest.CallFunctionWithRows(parser.ForEachChunk, []map[string]interface{}{
{
"id": 3,
"name": "yet another fake name",
"age": 44,
},
})
return err
},
}
s := Service{
db: mockDB,
streamChunkSize: 2,
}
var users []UserEntity
err := s.StreamAllUsers(context.TODO(), func(u UserEntity) error {
users = append(users, u)
return nil
})
assert.Equal(t, nil, err)
assert.Equal(t, 3, len(users))
expectedUsers := []UserEntity{
{
ID: 1,
Name: nullable.String("fake name"),
Age: nullable.Int(42),
},
{
ID: 2,
Name: nullable.String("another fake name"),
Age: nullable.Int(43),
},
{
ID: 3,
Name: nullable.String("yet another fake name"),
Age: nullable.Int(44),
},
}
assert.Equal(t, expectedUsers, users)
})
}
func TestDeleteUserWithKsqlMock(t *testing.T) {
t.Run("should call ksql.Delete correctly", func(t *testing.T) {
var ids []interface{}
mockDB := ksql.Mock{
DeleteFn: func(ctx context.Context, table ksql.Table, idOrObj interface{}) error {
ids = append(ids, idOrObj)
return nil
},
}
s := Service{
db: mockDB,
streamChunkSize: 100,
}
err := s.DeleteUser(context.TODO(), 42)
assert.Equal(t, nil, err)
assert.Equal(t, 1, len(ids))
assert.Equal(t, 42, ids[0])
})
}