登录
首页 >  Golang >  Go问答

测试 Go Mock Repository 在用例循环内的方法

来源:stackoverflow

时间:2024-02-12 08:00:30 374浏览 收藏

小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《测试 Go Mock Repository 在用例循环内的方法》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!

问题内容

我在使用 testify 测试存储库模拟数据库时遇到问题。

我想测试一个为每次迭代创建记录数据库的服务/用例。这是代码:

此代码包含数据库的模拟

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

此用例内的逻辑是为每个项目数 (numberofitems 变量) 保存 tododetail

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 次,那么我们必须提供 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 次迭代

为了对一系列模拟响应运行相同的测试,mock 有一个 .once() 方法,该方法可以启用对每个需要的结果重复一次模拟。

// array to loop through
todoDetailArray := []TodoDetail{todoDetail1, todoDetail2}

// loop through mocks for each test scenario
for eachTodoDetail := range todoDetailArray {
    repository.Mock.On("CreateTodoDetail", eachTodoDetail).Return(eachTodoDetail).Once()
    ...
}

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>