Updated: November 26, 2020 Video added
counterfeiter has been one of those tools we can not live without when building software in Go, specially because we build our enterprise systems using Domain Driven Design and we heavily use Dependency Injection to properly separate and test layers independently.
I briefly mentioned counterfeiter
in my previous Go Tool post, this time I will dive a bit deeper.
counterfeiter
is useful when using generate
directives in your code to automatically generate Fakes/Doubles/Mocks from dependent interfaces you define in your code.
For example, assuming you have the following code:
type Writer interface {
Write() error
}
And you have a piece of code like:
func WriteSomething(w Writer) bool {
if err := w.Write(); err != nil {
return false
}
return true
}
Adding the following directive:
//go:generate counterfeiter -o fake/writer.gen.go -fake-name Writer . Writer
counterfeiter
will generate a new type fake.Writer
that will allow you to use those instances as dummies, as well as giving you full control to fake, stub, mock and spy that said instance.
Using this simple method in this interface, the generated methods include:
Write() error
: to satisfy the interface,WriteCallCount() int
: to determine how many times the method was called,WriteCalls(func() error)
: to define a method that returns the same as the original interface, equal tow.WriteStub
but goroutine-safe,WriteReturns(error)
: to return the value all the timesWrite
is called, andWriteReturnsOnCall(int, error)
: to return specific values for specific calls at specific times.
With those autogenerated methods you have more than enough to properly test your external dependencies and how they affect your internal flow.
counterfeiter
is a really powerful tool. Highly recommended.