首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将对GitHub的调用存根以进行测试?

如何将对GitHub的调用存根以进行测试?
EN

Stack Overflow用户
提问于 2021-09-24 14:28:13
回答 1查看 153关注 0票数 1

我需要使用go-github创建一个Pull请求注释,我的代码可以工作,但现在我想为它编写测试(是的,我知道测试应该放在第一位),这样我就不会在测试期间实际调用真正的GitHub服务。

我已经读了3篇关于golang存根和嘲笑的博客,但是,作为一个刚接触golang的人,尽管有this discussion on go-github issues,我还是有点迷茫。例如,我编写了以下函数:

代码语言:javascript
复制
// this is my function
func GetClient(token string, url string) (*github.Client, context.Context, error) {
    ctx := context.Background()
    ts := oauth2.StaticTokenSource(
        &oauth2.Token{AccessToken: token},
    )
    tc := oauth2.NewClient(ctx, ts)
    client, err := github.NewEnterpriseClient(url, url, tc)

    if err != nil {
        fmt.Printf("error creating github client: %q", err)
        return nil, nil, err
    }
    return client, ctx, nil
}

我怎么能把它弄坏呢?

类似地,我有这样的想法:

代码语言:javascript
复制
func GetPRComments(ctx context.Context, client *github.Client) ([]*github.IssueComment, *github.Response, error)  {
    opts := &github.IssueListCommentsOptions{
        ListOptions: github.ListOptions{
            Page:    1,
            PerPage: 30,
        },
    }
    githubPrNumber, err := strconv.Atoi(os.Getenv("GITHUB_PR_NUMBER"))
    if err != nil || githubPrNumber == 0 {
      panic("error: GITHUB_PR_NUMBER is not numeric or empty")
    }

    // use Issues API for PR comments since GitHub docs say "This may seem counterintuitive... but a...Pull Request is just an Issue with code"
    comments, response, err := client.Issues.ListComments(
          ctx,
          os.Getenv("GITHUB_OWNER"),
          os.Getenv("GITHUB_REPO"),
          githubPrNumber,
          opts)
    if err != nil {
        return nil, nil, err
    }
    return comments, response, nil
}

我该如何处理它呢?

我的想法也许是先创建自己的结构来使用依赖注入,但我不确定如何使用,所以目前我有这样的想法:

代码语言:javascript
复制
func TestGetClient(t *testing.T) {
    client, ctx, err := GetClient(os.Getenv("GITHUB_TOKEN"), "https://example.com/api/v3/")
    c, r, err := GetPRComments(ctx, client)
    ...
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-27 07:02:51

我会从一个接口开始:

代码语言:javascript
复制
type ClientProvider interface {
  GetClient(token string, url string) (*github.Client, context.Context, error)
}

在测试需要调用GetClient的单元时,请确保依赖于您的ClientProvider接口:

代码语言:javascript
复制
func YourFunctionThatNeedsAClient(clientProvider ClientProvider) error {
  // build you token and url

  // get a github client
  client, ctx, err := clientProvider.GetClient(token, url)
  
  // do stuff with the client

  return nil
}

现在,在您的测试中,您可以像这样构造存根:

代码语言:javascript
复制
// A mock/stub client provider, set the client func in your test to mock the behavior
type MockClientProvider struct {
  GetClientFunc func(string, string) (*github.Client, context.Context, error)
}

// This will establish for the compiler that MockClientProvider can be used as the interface you created
func (provider *MockClientProvider) GetClient(token string, url string) (*github.Client, context.Context, error) {
  return provider.GetClientFunc(token, url)
}

// Your unit test
func TestYourFunctionThatNeedsAClient(t *testing.T) {
  mockGetClientFunc := func(token string, url string) (*github.Client, context.Context, error) {
    // do your setup here
    return nil, nil, nil // return something better than this
  }

  mockClientProvider := &MockClientProvider{GetClientFunc: mockGetClientFunc}

  // Run your test
  err := YourFunctionThatNeedsAClient(mockClientProvider)

  // Assert your result
}

这些想法不是我自己的,我是从我的前辈那里借来的;Mat Ryer在一个关于“惯用golang”的伟大视频中提出了这一点(以及其他想法)。

如果你想要存根github客户端本身,可以使用类似的方法,如果github.Client是一个结构,你可以用一个接口来隐藏它。如果它已经是一个接口,则上面的方法直接起作用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69316696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档