【问题标题】:How to mock a struct if you directly access its fields如果直接访问其字段,如何模拟结构
【发布时间】:2017-03-13 08:12:27
【问题描述】:

我正在编写一个作为 Github API 客户端的程序。我使用 https://github.com/google/go-github 访问 API。我有一个函数接受 github.Client 作为参数之一,并使用它从拉取请求中检索提交。我想用一些假数据来测试这个函数。

在这里的文章中:https://nathanleclaire.com/blog/2015/10/10/interfaces-and-composition-for-effective-unit-testing-in-golang/ 我读到,我应该创建一个将由 github 客户端实现的接口,然后在我的测试中,创建一个也将实现它的模拟。我的问题是,go-github 使用以下语义来检索拉取请求:

prs, resp, err := client.PullRequests.List("user", "repo", opt)

然而,接口允许您指定应该实现的方法,但不能指定字段。那么如何模拟 github.Client 对象以便可以在上述语义中使用它呢?

【问题讨论】:

  • 无需模拟已导出字段的内容:只需让自己成为 github.Client。
  • 但我不想要一个真正的 github.Client 连接到 API。我想要返回静态数据的东西。
  • 实现此目的的一种方法是声明您自己的接口。然后用两个不同的结构来实现它,第一个简单地调用 github API,另一个是你的假的。
  • 是的,这就是我想做的。但是我可以在界面中声明一个字段吗?只能在接口中声明 IIUC 方法。
  • @zefciu:将操作包装到自定义函数中不是一种选择吗?即var callDependency = func (client *github.Client) (*wrappedGithubResponse, error) {},然后在您的测试中覆盖这些函数?

标签: testing go interface mocking


【解决方案1】:

在您的情况下可能不实用,特别是如果您使用来自 github.Client 的大量功能,但您可以使用嵌入来创建实现您定义的接口的新结构。

type mockableClient struct {
    github.Client
}

func (mc *mockableClient) ListPRs(
owner string, repo string, opt *github.PullRequestListOptions) (
[]*github.PullRequest, *github.Response, error) {

return mc.Client.PullRequests.List(owner, repo, opt)
}


type clientMocker interface {
    Do(req *http.Request, v interface{}) (*github.Response, error)

    ListPRs(string,string,*github.PullRequestListOptions) (
[]*github.PullRequest, *github.Response, error)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多