mirror of https://github.com/VinGarcia/ksql.git
480 lines
14 KiB
Go
480 lines
14 KiB
Go
// This test was written mostly for test coverage since the mock is trivial
|
|
package ksql_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/vingarcia/ksql"
|
|
tt "github.com/vingarcia/ksql/internal/testtools"
|
|
)
|
|
|
|
func TestMock(t *testing.T) {
|
|
UsersTable := ksql.NewTable("users", "id")
|
|
type User struct {
|
|
ID int `ksql:"id"`
|
|
Name string `ksql:"name"`
|
|
Age int `ksql:"age"`
|
|
}
|
|
|
|
t.Run("testing unset behaviors for all methods", func(t *testing.T) {
|
|
t.Run("Insert should panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
panicPayload := tt.PanicHandler(func() {
|
|
mock.Insert(ctx, UsersTable, &User{
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.Mock.Insert(", "ksql.Mock.InsertFn", "not set")
|
|
})
|
|
|
|
t.Run("Patch should panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
panicPayload := tt.PanicHandler(func() {
|
|
mock.Patch(ctx, UsersTable, &User{
|
|
ID: 4242,
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.Mock.Patch(", "ksql.Mock.PatchFn", "not set")
|
|
})
|
|
|
|
t.Run("Delete should panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
panicPayload := tt.PanicHandler(func() {
|
|
mock.Delete(ctx, UsersTable, &User{
|
|
ID: 4242,
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.Mock.Delete(", "ksql.Mock.DeleteFn", "not set")
|
|
})
|
|
|
|
t.Run("Query should panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
panicPayload := tt.PanicHandler(func() {
|
|
var users []User
|
|
mock.Query(ctx, &users, "SELECT * FROM user WHERE age = ?", 42)
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.Mock.Query(", "ksql.Mock.QueryFn", "not set")
|
|
})
|
|
|
|
t.Run("QueryOne should panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
panicPayload := tt.PanicHandler(func() {
|
|
var user User
|
|
mock.QueryOne(ctx, &user, "SELECT * FROM user WHERE id = ?", 4242)
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.Mock.QueryOne(", "ksql.Mock.QueryOneFn", "not set")
|
|
})
|
|
|
|
t.Run("QueryChunks should panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
panicPayload := tt.PanicHandler(func() {
|
|
var users []User
|
|
mock.QueryChunks(ctx, ksql.ChunkParser{
|
|
Query: "SELECT * FROM users WHERE age = ?",
|
|
Params: []interface{}{
|
|
4242,
|
|
},
|
|
ChunkSize: 10,
|
|
ForEachChunk: func(chunk []User) error {
|
|
users = append(users, chunk...)
|
|
return nil
|
|
},
|
|
})
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.Mock.QueryChunks(", "ksql.Mock.QueryChunksFn", "not set")
|
|
})
|
|
|
|
t.Run("Exec should panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
panicPayload := tt.PanicHandler(func() {
|
|
mock.Exec(ctx, "INSERT INTO users_permissions(user_id, permission_id) VALUES (?, ?)", 4242, 4)
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.Mock.Exec(", "ksql.Mock.ExecFn", "not set")
|
|
})
|
|
|
|
t.Run("Transaction should not panic", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
mock := ksql.Mock{}
|
|
|
|
executed := false
|
|
panicPayload := tt.PanicHandler(func() {
|
|
mock.Transaction(ctx, func(db ksql.Provider) error {
|
|
executed = true
|
|
return nil
|
|
})
|
|
})
|
|
|
|
tt.AssertEqual(t, panicPayload, nil)
|
|
tt.AssertEqual(t, executed, true)
|
|
})
|
|
})
|
|
|
|
t.Run("should call the user provided behavior correctly", func(t *testing.T) {
|
|
t.Run("Insert", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
var capturedArgs struct {
|
|
ctx context.Context
|
|
table ksql.Table
|
|
record interface{}
|
|
}
|
|
mock := ksql.Mock{
|
|
InsertFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
|
|
capturedArgs.ctx = ctx
|
|
capturedArgs.table = table
|
|
capturedArgs.record = record
|
|
return fmt.Errorf("fake-error")
|
|
},
|
|
}
|
|
err := mock.Insert(ctx, UsersTable, &User{
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
|
|
tt.AssertErrContains(t, err, "fake-error")
|
|
tt.AssertEqual(t, capturedArgs.ctx, ctx)
|
|
tt.AssertEqual(t, capturedArgs.table, UsersTable)
|
|
tt.AssertEqual(t, capturedArgs.record, &User{
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
})
|
|
|
|
t.Run("Patch", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
var capturedArgs struct {
|
|
ctx context.Context
|
|
table ksql.Table
|
|
record interface{}
|
|
}
|
|
mock := ksql.Mock{
|
|
PatchFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
|
|
capturedArgs.ctx = ctx
|
|
capturedArgs.table = table
|
|
capturedArgs.record = record
|
|
return fmt.Errorf("fake-error")
|
|
},
|
|
}
|
|
err := mock.Patch(ctx, UsersTable, &User{
|
|
ID: 4242,
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
|
|
tt.AssertErrContains(t, err, "fake-error")
|
|
tt.AssertEqual(t, capturedArgs.ctx, ctx)
|
|
tt.AssertEqual(t, capturedArgs.table, UsersTable)
|
|
tt.AssertEqual(t, capturedArgs.record, &User{
|
|
ID: 4242,
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
})
|
|
|
|
t.Run("Delete", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
var capturedArgs struct {
|
|
ctx context.Context
|
|
table ksql.Table
|
|
record interface{}
|
|
}
|
|
mock := ksql.Mock{
|
|
DeleteFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
|
|
capturedArgs.ctx = ctx
|
|
capturedArgs.table = table
|
|
capturedArgs.record = record
|
|
return fmt.Errorf("fake-error")
|
|
},
|
|
}
|
|
err := mock.Delete(ctx, UsersTable, &User{
|
|
ID: 4242,
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
|
|
tt.AssertErrContains(t, err, "fake-error")
|
|
tt.AssertEqual(t, capturedArgs.ctx, ctx)
|
|
tt.AssertEqual(t, capturedArgs.table, UsersTable)
|
|
tt.AssertEqual(t, capturedArgs.record, &User{
|
|
ID: 4242,
|
|
Name: "fake-name",
|
|
Age: 42,
|
|
})
|
|
})
|
|
|
|
t.Run("Query", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
var capturedArgs struct {
|
|
ctx context.Context
|
|
records interface{}
|
|
query string
|
|
params []interface{}
|
|
}
|
|
mock := ksql.Mock{
|
|
QueryFn: func(ctx context.Context, records interface{}, query string, params ...interface{}) error {
|
|
capturedArgs.ctx = ctx
|
|
capturedArgs.records = records
|
|
capturedArgs.query = query
|
|
capturedArgs.params = params
|
|
return fmt.Errorf("fake-error")
|
|
},
|
|
}
|
|
var users []User
|
|
err := mock.Query(ctx, &users, "SELECT * FROM user WHERE age = ?", 42)
|
|
|
|
tt.AssertErrContains(t, err, "fake-error")
|
|
tt.AssertEqual(t, capturedArgs.ctx, ctx)
|
|
tt.AssertEqual(t, capturedArgs.records, &users)
|
|
tt.AssertEqual(t, capturedArgs.query, "SELECT * FROM user WHERE age = ?")
|
|
tt.AssertEqual(t, capturedArgs.params, []interface{}{42})
|
|
})
|
|
|
|
t.Run("QueryOne", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
var capturedArgs struct {
|
|
ctx context.Context
|
|
record interface{}
|
|
query string
|
|
params []interface{}
|
|
}
|
|
mock := ksql.Mock{
|
|
QueryOneFn: func(ctx context.Context, record interface{}, query string, params ...interface{}) error {
|
|
capturedArgs.ctx = ctx
|
|
capturedArgs.record = record
|
|
capturedArgs.query = query
|
|
capturedArgs.params = params
|
|
return fmt.Errorf("fake-error")
|
|
},
|
|
}
|
|
|
|
var user User
|
|
err := mock.QueryOne(ctx, &user, "SELECT * FROM user WHERE id = ?", 4242)
|
|
|
|
tt.AssertErrContains(t, err, "fake-error")
|
|
tt.AssertEqual(t, capturedArgs.ctx, ctx)
|
|
tt.AssertEqual(t, capturedArgs.record, &user)
|
|
tt.AssertEqual(t, capturedArgs.query, "SELECT * FROM user WHERE id = ?")
|
|
tt.AssertEqual(t, capturedArgs.params, []interface{}{4242})
|
|
})
|
|
|
|
t.Run("QueryChunks", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
var capturedArgs struct {
|
|
ctx context.Context
|
|
parser ksql.ChunkParser
|
|
}
|
|
mock := ksql.Mock{
|
|
QueryChunksFn: func(ctx context.Context, parser ksql.ChunkParser) error {
|
|
capturedArgs.ctx = ctx
|
|
capturedArgs.parser = parser
|
|
return fmt.Errorf("fake-error")
|
|
},
|
|
}
|
|
|
|
var users []User
|
|
chunkParserFunc := func(chunk []User) error {
|
|
users = append(users, chunk...)
|
|
return nil
|
|
}
|
|
err := mock.QueryChunks(ctx, ksql.ChunkParser{
|
|
Query: "SELECT * FROM users WHERE age = ?",
|
|
Params: []interface{}{
|
|
4242,
|
|
},
|
|
ChunkSize: 10,
|
|
ForEachChunk: chunkParserFunc,
|
|
})
|
|
|
|
tt.AssertErrContains(t, err, "fake-error")
|
|
tt.AssertEqual(t, capturedArgs.ctx, ctx)
|
|
tt.AssertEqual(t, capturedArgs.parser.Query, "SELECT * FROM users WHERE age = ?")
|
|
tt.AssertEqual(t, capturedArgs.parser.Params, []interface{}{
|
|
4242,
|
|
})
|
|
tt.AssertEqual(t, capturedArgs.parser.ChunkSize, 10)
|
|
})
|
|
|
|
t.Run("Exec", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
var capturedArgs struct {
|
|
ctx context.Context
|
|
query string
|
|
params []interface{}
|
|
}
|
|
mock := ksql.Mock{
|
|
ExecFn: func(ctx context.Context, query string, params ...interface{}) (ksql.Result, error) {
|
|
capturedArgs.ctx = ctx
|
|
capturedArgs.query = query
|
|
capturedArgs.params = params
|
|
return ksql.NewMockResult(42, 42), fmt.Errorf("fake-error")
|
|
},
|
|
}
|
|
r, err := mock.Exec(ctx, "INSERT INTO users_permissions(user_id, permission_id) VALUES (?, ?)", 4242, 4)
|
|
|
|
tt.AssertErrContains(t, err, "fake-error")
|
|
rowsAffected, err := r.RowsAffected()
|
|
tt.AssertNoErr(t, err)
|
|
tt.AssertEqual(t, rowsAffected, int64(42))
|
|
lastInsertID, err := r.LastInsertId()
|
|
tt.AssertNoErr(t, err)
|
|
tt.AssertEqual(t, lastInsertID, int64(42))
|
|
tt.AssertEqual(t, capturedArgs.ctx, ctx)
|
|
tt.AssertEqual(t, capturedArgs.query, "INSERT INTO users_permissions(user_id, permission_id) VALUES (?, ?)")
|
|
tt.AssertEqual(t, capturedArgs.params, []interface{}{4242, 4})
|
|
})
|
|
|
|
t.Run("Transaction", func(t *testing.T) {
|
|
ctx := context.Background()
|
|
executingMockedTransaction := false
|
|
mock := ksql.Mock{
|
|
TransactionFn: func(ctx context.Context, fn func(db ksql.Provider) error) error {
|
|
executingMockedTransaction = true
|
|
return nil
|
|
},
|
|
}
|
|
|
|
executed := false
|
|
mock.Transaction(ctx, func(db ksql.Provider) error {
|
|
executed = true
|
|
return nil
|
|
})
|
|
|
|
tt.AssertEqual(t, executingMockedTransaction, true)
|
|
tt.AssertEqual(t, executed, false)
|
|
})
|
|
})
|
|
|
|
t.Run("SetFallbackDatabase", func(t *testing.T) {
|
|
testMock := ksql.Mock{}
|
|
dbMock := ksql.Mock{
|
|
InsertFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
|
|
return fmt.Errorf("called from InsertFn")
|
|
},
|
|
PatchFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
|
|
return fmt.Errorf("called from PatchFn")
|
|
},
|
|
DeleteFn: func(ctx context.Context, table ksql.Table, record interface{}) error {
|
|
return fmt.Errorf("called from DeleteFn")
|
|
},
|
|
QueryFn: func(ctx context.Context, records interface{}, query string, params ...interface{}) error {
|
|
return fmt.Errorf("called from QueryFn")
|
|
},
|
|
QueryOneFn: func(ctx context.Context, record interface{}, query string, params ...interface{}) error {
|
|
return fmt.Errorf("called from QueryOneFn")
|
|
},
|
|
QueryChunksFn: func(ctx context.Context, parser ksql.ChunkParser) error {
|
|
return fmt.Errorf("called from QueryChunksFn")
|
|
},
|
|
ExecFn: func(ctx context.Context, query string, params ...interface{}) (ksql.Result, error) {
|
|
return nil, fmt.Errorf("called from ExecFn")
|
|
},
|
|
TransactionFn: func(ctx context.Context, fn func(db ksql.Provider) error) error {
|
|
return fmt.Errorf("called from TransactionFn")
|
|
},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
testMock = testMock.SetFallbackDatabase(dbMock)
|
|
|
|
var user User
|
|
err := testMock.Insert(ctx, UsersTable, &user)
|
|
tt.AssertErrContains(t, err, "called from InsertFn")
|
|
err = testMock.Patch(ctx, UsersTable, &user)
|
|
tt.AssertErrContains(t, err, "called from PatchFn")
|
|
err = testMock.Delete(ctx, UsersTable, &user)
|
|
tt.AssertErrContains(t, err, "called from DeleteFn")
|
|
|
|
var users []User
|
|
err = testMock.Query(ctx, &users, "fake-query")
|
|
tt.AssertErrContains(t, err, "called from QueryFn")
|
|
err = testMock.QueryOne(ctx, &user, "fake-query")
|
|
tt.AssertErrContains(t, err, "called from QueryOneFn")
|
|
err = testMock.QueryChunks(ctx, ksql.ChunkParser{})
|
|
tt.AssertErrContains(t, err, "called from QueryChunksFn")
|
|
_, err = testMock.Exec(ctx, "fake-query")
|
|
tt.AssertErrContains(t, err, "called from ExecFn")
|
|
err = testMock.Transaction(ctx, func(db ksql.Provider) error {
|
|
return nil
|
|
})
|
|
tt.AssertErrContains(t, err, "called from TransactionFn")
|
|
})
|
|
}
|
|
|
|
func TestMockResult(t *testing.T) {
|
|
t.Run("LastInsertId", func(t *testing.T) {
|
|
t.Run("the constructor should work correctly", func(t *testing.T) {
|
|
result := ksql.NewMockResult(24, 42)
|
|
lastInsertID, err := result.LastInsertId()
|
|
tt.AssertNoErr(t, err)
|
|
tt.AssertEqual(t, lastInsertID, int64(24))
|
|
})
|
|
|
|
t.Run("should panic if no values are provided", func(t *testing.T) {
|
|
result := ksql.MockResult{}
|
|
|
|
panicPayload := tt.PanicHandler(func() {
|
|
result.LastInsertId()
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.MockResult.LastInsertId(", "ksql.MockResult.LastInsertIdFn", "not set")
|
|
})
|
|
})
|
|
|
|
t.Run("RowsAffected", func(t *testing.T) {
|
|
t.Run("the constructor should work correctly", func(t *testing.T) {
|
|
result := ksql.NewMockResult(24, 42)
|
|
rowsAffected, err := result.RowsAffected()
|
|
tt.AssertNoErr(t, err)
|
|
tt.AssertEqual(t, rowsAffected, int64(42))
|
|
})
|
|
|
|
t.Run("should panic if no values are provided", func(t *testing.T) {
|
|
result := ksql.MockResult{}
|
|
|
|
panicPayload := tt.PanicHandler(func() {
|
|
result.RowsAffected()
|
|
})
|
|
|
|
err, ok := panicPayload.(error)
|
|
tt.AssertEqual(t, ok, true)
|
|
tt.AssertErrContains(t, err, "ksql.MockResult.RowsAffected(", "ksql.MockResult.RowsAffectedFn", "not set")
|
|
})
|
|
})
|
|
}
|