如何模拟一个结构体,如果你直接访问它的字段。

huangapple go评论83阅读模式
英文:

How to mock a struct if you directly access its fields

问题

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

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

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

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

英文:

I am writing a program that acts as a client of Github API. I use https://github.com/google/go-github to access the API. I have a function that accepts a github.Client as one of the argumenta and uses it to retrieve commits from a pull request. I want to test this function with some fake data.

In the article here: https://nathanleclaire.com/blog/2015/10/10/interfaces-and-composition-for-effective-unit-testing-in-golang/ I read, that I should create an interface that would be implemented by github client, and then in my tests, create a mock that would also implement it. My problem is, that go-github uses the following semantics to retrieve pull request:

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

The interfaces however allow you to specify methods that should be implemented, but not fields. So how can I mock the github.Client object so it can be used in the above semantics?

答案1

得分: 3

这是翻译好的内容:

在你的情况下可能不太实用,特别是如果你正在使用很多来自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)
}

希望对你有帮助!

英文:

It may not be practical in your case, especially if you're using a lot of functionality from github.Client but you can use embedding to create a new structure that implements an interface you define.

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

huangapple
  • 本文由 发表于 2016年10月31日 16:45:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/40338890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定