In first post we have isolated our package. We could test it against real service xyz, but we want to isolate the package and perform a unit test.

We will use gomock.
Gomock is a mocking framework. It will generate a class who simulate the same behaviour as the original class, but we can determine which methods will be called, with input and outputs defined.

First of all we create an interface for Xyz and

Let’s create the mock. We can add the go:generate comment everywhere in the class, but is more tidy add it near the interface.

import _ ""  // we can remove this when first 

//go:generate mockgen -destination=../mocks/xyz.go -package=mocks . Xyz 
type Xyz interface {
	GetInfo(int) (*xyz.GetInfoOutput, error)

Note: we have to import only to generate the mock, we can remove when the tests are written.

go generate ./...

This will create a new package mocks with MockXyz, a mock of Xyz interface.

Now we can test our package!

First we have to create the mockCtrl, this will drive our mocks

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

Now we can create the object mockedXyz.

	mockedXyx := mocks.NewMockXyz(mockCtrl)

we can finally create our service, call the function and test the return value

	s := New(mockedXyx)

	out, err := s.GetInfoFromXyz()

	assert.Nil(t, err)
	assert.Equal(t, "something", out)


Let’s test our package!

─➤  go test
--- FAIL: TestService_GetInfoFromXyz (0.00s)
    mypackage.go:22: Unexpected call to *mypackage.MockXyz.GetInfo([42]) at /home/alorenzi/progetti/playground/mypackage/mypackage.go:22 because: there are no expected calls of the method "GetInfo" for that receiver
FAIL       0.002s

We have forgotten to explain exactly which functions will be called and the responses. Before call the function s.GetInfoFromXyz() let’s write what we expect from our mock:

		InfoINeed: "something",
	}, nil)

Now the test will work fine:

# go test -count=1
ok	0.002s

You can find the code (on my GitHub)[]!