Original post

I have a small piece of code that goes communicates with GitHub API. It authenticates myself using my Token. It reads the token from my shell environment

export GHTOKEN=“foobar”

And then, after getting authenticated, it visits one my github repositories (specifically the one called “ghostfish”) and it fetches the description of it.

So I wanted to write some tests for it. That’s when all the confusion started … I didn’t want to spam github with my test, so I wanted to mock the function in a way so to avoid hitting the actual 3rd party service – that is github api.

What I did:

  • I converted my functions into methods
  • I created an interface that implements those methods
  • I used mockgen to generate the mock. Specifically the command was: mockgen -source=main. -destination=mocks/mock_githubClient. -package=$GOPACKAGE

Then, when I test for the coverage, I get 0%.

$ go tool cover -func cover.out                                                      
github.com/testf/main.go:24:    main            0.0%
github.com/testf/main.go:34:    Authenticated   0.0%
github.com/testf/main.go:44:    GetUserRepo     0.0%
total:                          (statements)    0.0%

How is that possible? I am confused …

Here’s the code, if you want to have a look:


package main

import (


var (
        GithubClient githubClientInterface = &githubClient{}

type githubClientInterface interface {
        Authenticated(env string) *github.Client
        GetUserRepo(client *github.Client, user string) (*github.Repository, error)

type githubClient struct{}

func main() {
        client := GithubClient.Authenticated("GHTOKEN")
        repo, err := GithubClient.GetUserRepo(client, "drpaneas")
        if err != nil {

func (c *githubClient) Authenticated(env string) *github.Client {
        token := oauth2.Token{
                AccessToken: os.Getenv(env),
        tokenSource := oauth2.StaticTokenSource(&token)
        tc := oauth2.NewClient(context.Background(), tokenSource)
        client := github.NewClient(tc)
        return client

func (c *githubClient) GetUserRepo(client *github.Client, user string) (*github.Repository, error) {
        repo, _, err := client.Repositories.Get(context.Background(), user, "ghostfish")
        if err != nil {
                return nil, err
        return repo, err


package main

import (

        mocks "github.com/testf/mocks"

func TestWithGoMock(t *testing.T) {
        mockCtrl := gomock.NewController(t)
        defer mockCtrl.Finish()

        mockgithubClient := mocks.NewMockgithubClientInterface(mockCtrl)
        c := &github.Client{}
        client := mockgithubClient.Authenticated("whatever")

        s := "something"
        var x *string
        x = &s
        r := &github.Repository{Description: x}
        mockgithubClient.EXPECT().GetUserRepo(client, "drpaneas").AnyTimes().Return(r, nil)
        repo, _ := mockgithubClient.GetUserRepo(client, "drpaneas")
        output := fmt.Sprintf("%s", (repo.GetDescription()))
        if output != "something" {
                t.Error("It cannot fetch the repository name")


// Code generated by MockGen. DO NOT EDIT.
// Source: main.go

// Package mock_main is a generated GoMock package.
package mock_main

import (
        gomock "github.com/golang/mock/gomock"
        github "github.com/google/go-github/v30/github"
        reflect "reflect"

// MockgithubClientInterface is a mock of githubClientInterface interface
type MockgithubClientInterface struct {
        ctrl     *gomock.Controller
        recorder *MockgithubClientInterfaceMockRecorder

// MockgithubClientInterfaceMockRecorder is the mock recorder for MockgithubClientInterface
type MockgithubClientInterfaceMockRecorder struct {
        mock *MockgithubClientInterface

// NewMockgithubClientInterface creates a new mock instance
func NewMockgithubClientInterface(ctrl *gomock.Controller) *MockgithubClientInterface {
        mock := &MockgithubClientInterface{ctrl: ctrl}
        mock.recorder = &MockgithubClientInterfaceMockRecorder{mock}
        return mock

// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockgithubClientInterface) EXPECT() *MockgithubClientInterfaceMockRecorder {
        return m.recorder

// Authenticated mocks base method
func (m *MockgithubClientInterface) Authenticated(env string) *github.Client {
        ret := m.ctrl.Call(m, "Authenticated", env)
        ret0, _ := ret[0].(*github.Client)
        return ret0

// Authenticated indicates an expected call of Authenticated
func (mr *MockgithubClientInterfaceMockRecorder) Authenticated(env interface{}) *gomock.Call {
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Authenticated", reflect.TypeOf((*MockgithubClientInterface)(nil).Authenticated), env)

// GetUserRepo mocks base method
func (m *MockgithubClientInterface) GetUserRepo(client *github.Client, user string) (*github.Repository, error) {
        ret := m.ctrl.Call(m, "GetUserRepo", client, user)
        ret0, _ := ret[0].(*github.Repository)
        ret1, _ := ret[1].(error)
        return ret0, ret1

// GetUserRepo indicates an expected call of GetUserRepo
func (mr *MockgithubClientInterfaceMockRecorder) GetUserRepo(client, user interface{}) *gomock.Call {
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserRepo", reflect.TypeOf((*MockgithubClientInterface)(nil).GetUserRepo), client, user)