ksql/examples/example_service/example_test_using_ksql_Moc...

254 lines
6.1 KiB
Go

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])
})
}