gomock example
Using gomock
on an interface and using the go tool gotests
for unit testing.
GitHub Webpage
WHAT IS GOMOCK
GoMock is a mock framework for Go.
Its useful for mocking an interface
It enjoys a somewhat official status as
part of the github.com/golang organization.
mockgen
is the code generation tool.
Install,
go get -u -v github.com/golang/mock/gomock
go install github.com/golang/mock/mockgen
Verify you have it,
$GOPATH/bin/mockgen
HOW TO USE GOMOCK
Four basic steps:
- Use mockgen to generate a mock for the interface you wish to mock
- In your test, create an instance of gomock.Controller and pass it
to your mock object’s constructor to obtain a mock object
- Call EXPECT() on your mocks to set up their expectations and return values
- Call Finish() on the mock controller to assert the mock’s expectations
More on this in a bit. First lets look at the packages.
CREATURES PACKAGE
Lets describe a werewolf and a vampire in our creatures package
/creatures/creatures.go
,
type Werewolf struct {
TimeofDay string
}
type Vampire struct {
Age int
}
Where werewolf has the following methods,
- Kind() - during day is a human, otherwise werewolf.
- Fly() - no
- Sound() - during days says "hell0" otherwise "howls".
And vampire has the following methods,
- Kind() - older than 100, he's a vampire.
- Fly() - yes
- Sound() - "I want to drink your blood"
LABORATORY PACKAGE
I created another package laboratory where I keep my creatures.
type Creatures interface {
Kind() string
Fly() bool
Sound() string
}
Where I have two functions Greet
and FlyAway
using the interface.
RUN
go run helloween.go
GENERATE TEST FILE USING GOTESTS
The following command will generate a test file with the hooks
in place to perform unit testing,
cd laboratory
gotests -w -all .
cd creatures
gotests -w -all .
RUN YOUR TEST & COVERAGE (0% COVERED)
Now if you run go test,
cd ..
go test -v -cover laboratory/*
go test -v -cover creatures/*
Optional commands,
go test -coverprofile coverage.out
go tool cover -html=coverage.out -o coverage.html
You should get 0% covered,
PASS
coverage: 0.0% of statements
ADD TESTS TO CREATURES PACKAGE (100% COVERED)
There are 6 methods in the creatures package.
As an example lets add tests to the function TestWerewolf_Kind(t *testing.T)
,
// TODO: Add test cases.
{
"Test1",
fields{
TimeofDay: "day",
},
"human",
},
{
"Test2",
fields{
TimeofDay: "night",
},
"werewolf",
},
Do this for all six methods in the creatures package. Now when you run your test,
cd creatures
go test -v -cover .
go test -coverprofile coverage.out
go tool cover -html=coverage.out -o coverage.html
Your coverage shall now be,
PASS
coverage: 100% of statements
ADD TESTS TO LABORATORY PACKAGE (100% COVERED)
We have two functions to test; Greet()
and FlyAway()
that each use an interface.
So lets mock that interface.
Using mockgen, we create a file mockcreature.go
,
cd laboratory
mockgen -source=laboratory.go -package=laboratory -destination=mockcreature.go
To use add the following lines to the top of your test function
func TestGreet(t *testing.T) {
func TestGreet(t *testing.T) {
var ctrl = gomock.NewController(t)
defer ctrl.Finish()
var mockcreature = NewMockCreatures(ctrl)
mockcreature.EXPECT().Sound().Times(1).Return("poo")
Where you test is,
// TODO: Add test cases.
{
"Test1",
args{
c: mockcreature,
},
"poo",
},
Do the same to the other function. Now run your tests,
cd laboratory
go test -v -cover .
go test -coverprofile coverage.out
go tool cover -html=coverage.out -o coverage.html