为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
小唯快跑啊 2022-10-04 16:36:58
我需要使用go-github创建一个拉取请求注释,我的代码可以工作,但现在我想为它编写测试(是的,我知道测试应该放在第一位),这样我就不会在测试期间实际调用真正的GitHub服务。我已经阅读了3篇关于golang茬蛰和嘲笑的博客,但是,作为golang的新手,尽管对go-github问题进行了讨论,但我还是有点迷茫。例如,我编写了以下函数:// this is my functionfunc 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}我怎么能存根呢?同样,我有这个: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}我应该如何存根?我的想法是也许通过首先创建自己的结构来使用依赖注入,但我不确定如何,所以目前我有这个:func TestGetClient(t *testing.T) {    client, ctx, err := GetClient(os.Getenv("GITHUB_TOKEN"), "https://example.com/api/v3/")    c, r, err := GetPRComments(ctx, client)    ...}
查看完整描述

1 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

我会从一个界面开始:


type ClientProvider interface {

  GetClient(token string, url string) (*github.Client, context.Context, error)

}

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


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

}

现在,在您的测试中,您可以构造如下存根:


// 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)。客户端是一个结构,你可以用一个接口来隐藏它。如果它已经是一个接口,则上述方法直接起作用。


查看完整回答
反对 回复 2022-10-04
  • 1 回答
  • 0 关注
  • 149 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号