Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A library to aid unittesting code that uses Golang's Github SDK

License

NotificationsYou must be signed in to change notification settings

migueleliasweb/go-github-mock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go ReferenceGo Report Card

A library to aid unittesting code that uses Golang's Github SDK

Installation

go get github.com/migueleliasweb/go-github-mock

Features

  • Create mocks for successive calls for the same endpoint
  • Pagination support (seemock.WithRequestMatchPages)
  • Mock error returns
  • High level abstraction helps writing readabe unittests (seemock.WithRequestMatch)
  • Lower level abstraction for advanced uses (seemock.WithRequestMatchHandler)
  • Mock rate limiting errors from the api (seemock.WithRateLimit)

Examples

import"github.com/migueleliasweb/go-github-mock/src/mock"

Multiple requests

mockedHTTPClient:=mock.NewMockedHTTPClient(mock.WithRequestMatch(mock.GetUsersByUsername,        github.User{Name:github.Ptr("foobar"),        },    ),mock.WithRequestMatch(mock.GetUsersOrgsByUsername,        []github.Organization{            {Name:github.Ptr("foobar123thisorgwasmocked"),            },        },    ),mock.WithRequestMatchHandler(mock.GetOrgsProjectsByOrg,http.HandlerFunc(func(w http.ResponseWriter,_*http.Request) {w.Write(mock.MustMarshal([]github.Project{                {Name:github.Ptr("mocked-proj-1"),                },                {Name:github.Ptr("mocked-proj-2"),                },            }))        }),    ),)c:=github.NewClient(mockedHTTPClient)ctx:=context.Background()user,_,userErr:=c.Users.Get(ctx,"myuser")// user.Name == "foobar"orgs,_,orgsErr:=c.Organizations.List(ctx,*(user.Name),nil,)// orgs[0].Name == "foobar123thisorgwasmocked"projs,_,projsErr:=c.Organizations.ListProjects(ctx,*orgs[0].Name,&github.ProjectListOptions{},)// projs[0].Name == "mocked-proj-1"// projs[1].Name == "mocked-proj-2"

Returning empty results

mockedHTTPClient:=NewMockedHTTPClient(WithRequestMatch(GetReposIssuesByOwnerByRepo,        []github.Issue{            {ID:github.Int64(123),Title:github.Ptr("Issue 1"),            },            {ID:github.Int64(456),Title:github.Ptr("Issue 2"),            },        },        []github.Issue{},    ),)c:=github.NewClient(mockedHTTPClient)ctx:=context.Background()issues1,_,repo1Err:=c.Issues.ListByRepo(ctx,"owner1","repo1",&github.IssueListByRepoOptions{})// len(issues1) == 2// repo1Err == nilissues2,_,repo2Err:=c.Issues.ListByRepo(ctx,"owner1","repo2",&github.IssueListByRepoOptions{})// len(issues2) == 0// repo2Err == nil

Mocking errors from the API

mockedHTTPClient:=mock.NewMockedHTTPClient(mock.WithRequestMatchHandler(mock.GetUsersByUsername,http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {mock.WriteError(w,http.StatusInternalServerError,"github went belly up or something",            )        }),    ),)c:=github.NewClient(mockedHTTPClient)ctx:=context.Background()user,_,userErr:=c.Users.Get(ctx,"someUser")// user == nilifuserErr==nil {ifghErr,ok:=userErr.(*github.ErrorResponse);ok {fmt.Println(ghErr.Message)// == "github went belly up or something"    }}

Mocking with pagination

mockedHTTPClient:=NewMockedHTTPClient(WithRequestMatchPages(GetOrgsReposByOrg,        []github.Repository{            {Name:github.Ptr("repo-A-on-first-page"),            },            {Name:github.Ptr("repo-B-on-first-page"),            },        },        []github.Repository{            {Name:github.Ptr("repo-C-on-second-page"),            },            {Name:github.Ptr("repo-D-on-second-page"),            },        },    ),)c:=github.NewClient(mockedHTTPClient)ctx:=context.Background()opt:=&github.RepositoryListByOrgOptions{ListOptions: github.ListOptions{// in fact, the perPage option is ignored my the mocks// but this would be present in production codePerPage:2,    },}varallRepos []*github.Repositoryfor {repos,resp,listErr:=c.Repositories.ListByOrg(ctx,"foobar",opt)iflistErr!=nil {t.Errorf("error listing repositories: %s",listErr.Error())    }// len(repos) == 2allRepos=append(allRepos,repos...)ifresp.NextPage==0 {break    }opt.Page=resp.NextPage}// matches the mock definitions len(page[0]) + len(page[1])// len(allRepos) == 4

Mocking for GitHub Enterprise

Github Enterprise uses a different prefix for its endpoints. In order to use the correct endpoints, please use the different set of*Enterprise options:

  • WithRequestMatchEnterprise
  • WithRequestMatchPagesEnterprise
mockedHTTPClient:=mock.NewMockedHTTPClient(mock.WithRequestMatchEnterprise(// uses enterprise endpoints insteadmock.GetUsersByUsername,        github.User{Name:github.Ptr("foobar"),        },    ),)c:=githubEnterprise.NewClient(mockedHTTPClient)ctx:=context.Background()user,_,userErr:=c.Users.Get(ctx,"myuser")// user.Name == "foobar"

Mocking with rate limits

WithRateLimit uses a single rate-limiting middleware across all endpoints on the mock router.

NOTE: This is an alpha feature. Future changes might break compatibility, until a stable version is released.

mockedHTTPClient:=mock.NewMockedHTTPClient(mock.WithRequestMatchPages(mock.GetOrgsReposByOrg,        []github.Repository{{Name:github.Ptr(repoOne)}},        []github.Repository{{Name:github.Ptr(repoTwo)}},    ),// The rate limiter will allow 10 requests per second, and a burst size of 1.// These two options together mean that the rate of requests will be strictly enforced, so if any two requests are// made less than 1/10th of a second apart, the latter will be refused and come back with a rate limit error.mock.WithRateLimit(10,1),)

Why

Some conversations got started ongo-github#1800 sincego-github didn't provide an interface that could be easily reimplemented for unittests. After lots of conversations from the folks fromgo-github and quite a few PR ideas later, this style of testing was deemed not suitable to be part of the core SDK as it's not a feature of the API itself. Nonetheless, the ability of writing unittests for code that uses thego-github package is critical.

A reuseable, and not overly verbose, way of writing the tests was reached after some more interactions (months down the line) and here we are.

Thanks

Thanks for all ideas and feedback from the folks ingo-github.

License

This library is distributed under the MIT License found in LICENSE.

About

A library to aid unittesting code that uses Golang's Github SDK

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors14


[8]ページ先頭

©2009-2025 Movatter.jp