如何在用例的循环中测试 Go Mock Repository
How to test Go Mock Repository inside loop on usecase
我在使用 testify 测试存储库模拟数据库时遇到问题。
我想测试一个为每次迭代创建记录数据库的 service/use 案例。这是代码:
此代码包含数据库的模拟
mockrepository.go
package service
import(
"errors"
"github.com/stretchr/testify/mock"
)
type TestRepositoryMock struct {
Mock mock.Mock
}
func (repository *TestRepositoryMock) CreateTodo(todo *Todo) error {
arguments := repository.Mock.Called(todo)
if arguments.Get(0) == nil {
return errors.New("Error")
} else {
return nil
}
}
func (repository *TestRepositoryMock) CreateTodoDetail(todo *TodoDetail) error {
arguments := repository.Mock.Called(todo)
if arguments.Get(0) == nil {
return errors.New("Error")
} else if arguments.Get(1) == nil {
return errors.New("Error")
} else {
return nil
}
}
此用例中的逻辑是为每个项目数保存 TodoDetail (NumberOfItems variable)
usecase.go
package service
import(
"strconv"
)
type UseCase interface {
SaveTodo(numberOfItems int) (string, error)
}
func NewUseCase(repo Repository) UseCase {
return &useCase{repo: repo}
}
type useCase struct {
repo Repository
}
func (uc *useCase) SaveTodo(numberOfItems int) (string, error){
todo := Todo{
Title: "this is title",
}
uc.repo.CreateTodo(&todo)
for i := 0; i < numberOfItems; i++ {
todoDetail := TodoDetail{
ID: todo.ID,
Item: "item "+ strconv.Itoa(i),
}
uc.repo.CreateTodoDetail(&todoDetail)
}
return "success", nil
}
package service
import(
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
var repository = &TestRepositoryMock{Mock: mock.Mock{}}
var testService = useCase{repo: repository}
func TestService_SaveTodoSuccess(t *testing.T) {
todo := Todo{
Title: "this is title",
}
todoDetail := TodoDetail{
ID: todo.ID,
Item: "item 1",
}
repository.Mock.On("CreateTodo", &todo).Return(nil)
repository.Mock.On("CreateTodoDetail", &todoDetail).Return(nil).Once()
result, err := testService.SaveTodo(3)
assert.Nil(t, err)
assert.NotNil(t, result)
}
如何在for循环中测试CreateTodoDetail
的多次调用?
-已解决-
为了测试循环用例,我们应该提供大量模拟数据。与循环迭代相同。
例子。如果用例有 3 个迭代循环调用存储库三次,那么我们必须提供 3 个数据模拟。
代码应该是这样的:
func TestService_SaveTodoSuccess(t *testing.T) {
// Mock Entity Todo
todo := Todo{
Title: "this is title",
}
// Mock Entity TodoDetail
todoDetail1 := TodoDetail{
ID: todo.ID,
Item: "item 0",
}
todoDetail2 := TodoDetail{
ID: todo.ID,
Item: "item 1",
}
todoDetail3 := TodoDetail{
ID: todo.ID,
Item: "item 2",
}
repository.Mock.On("CreateTodo", &todo).Return(todo)
// calls 3 times "CreateTodoDetail" Repository
repository.Mock.On("CreateTodoDetail", &todoDetail1).Return(todoDetail1)
repository.Mock.On("CreateTodoDetail", &todoDetail2).Return(todoDetail2)
repository.Mock.On("CreateTodoDetail", &todoDetail3).Return(todoDetail3)
result, err := testService.SaveTodo(3)
assert.Nil(t, err)
assert.NotNil(t, result)
}
该场景在 todoDetail 上构建 3 个不同的数据以模拟 CreateTodoDetail
存储库
的 3 次迭代
我在使用 testify 测试存储库模拟数据库时遇到问题。
我想测试一个为每次迭代创建记录数据库的 service/use 案例。这是代码:
此代码包含数据库的模拟
mockrepository.go
package service
import(
"errors"
"github.com/stretchr/testify/mock"
)
type TestRepositoryMock struct {
Mock mock.Mock
}
func (repository *TestRepositoryMock) CreateTodo(todo *Todo) error {
arguments := repository.Mock.Called(todo)
if arguments.Get(0) == nil {
return errors.New("Error")
} else {
return nil
}
}
func (repository *TestRepositoryMock) CreateTodoDetail(todo *TodoDetail) error {
arguments := repository.Mock.Called(todo)
if arguments.Get(0) == nil {
return errors.New("Error")
} else if arguments.Get(1) == nil {
return errors.New("Error")
} else {
return nil
}
}
此用例中的逻辑是为每个项目数保存 TodoDetail (NumberOfItems variable)
usecase.go
package service
import(
"strconv"
)
type UseCase interface {
SaveTodo(numberOfItems int) (string, error)
}
func NewUseCase(repo Repository) UseCase {
return &useCase{repo: repo}
}
type useCase struct {
repo Repository
}
func (uc *useCase) SaveTodo(numberOfItems int) (string, error){
todo := Todo{
Title: "this is title",
}
uc.repo.CreateTodo(&todo)
for i := 0; i < numberOfItems; i++ {
todoDetail := TodoDetail{
ID: todo.ID,
Item: "item "+ strconv.Itoa(i),
}
uc.repo.CreateTodoDetail(&todoDetail)
}
return "success", nil
}
package service
import(
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
var repository = &TestRepositoryMock{Mock: mock.Mock{}}
var testService = useCase{repo: repository}
func TestService_SaveTodoSuccess(t *testing.T) {
todo := Todo{
Title: "this is title",
}
todoDetail := TodoDetail{
ID: todo.ID,
Item: "item 1",
}
repository.Mock.On("CreateTodo", &todo).Return(nil)
repository.Mock.On("CreateTodoDetail", &todoDetail).Return(nil).Once()
result, err := testService.SaveTodo(3)
assert.Nil(t, err)
assert.NotNil(t, result)
}
如何在for循环中测试CreateTodoDetail
的多次调用?
-已解决-
为了测试循环用例,我们应该提供大量模拟数据。与循环迭代相同。
例子。如果用例有 3 个迭代循环调用存储库三次,那么我们必须提供 3 个数据模拟。
代码应该是这样的:
func TestService_SaveTodoSuccess(t *testing.T) {
// Mock Entity Todo
todo := Todo{
Title: "this is title",
}
// Mock Entity TodoDetail
todoDetail1 := TodoDetail{
ID: todo.ID,
Item: "item 0",
}
todoDetail2 := TodoDetail{
ID: todo.ID,
Item: "item 1",
}
todoDetail3 := TodoDetail{
ID: todo.ID,
Item: "item 2",
}
repository.Mock.On("CreateTodo", &todo).Return(todo)
// calls 3 times "CreateTodoDetail" Repository
repository.Mock.On("CreateTodoDetail", &todoDetail1).Return(todoDetail1)
repository.Mock.On("CreateTodoDetail", &todoDetail2).Return(todoDetail2)
repository.Mock.On("CreateTodoDetail", &todoDetail3).Return(todoDetail3)
result, err := testService.SaveTodo(3)
assert.Nil(t, err)
assert.NotNil(t, result)
}
该场景在 todoDetail 上构建 3 个不同的数据以模拟 CreateTodoDetail
存储库