Skip to content
A tool for generating self-contained, type-safe test doubles in go
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
arguments use v6 import path for go module v2+ compatibilty Mar 21, 2019
fixtures describe how to use with go modules, remove go version from go.mod Mar 21, 2019
generator use v6 import path for go module v2+ compatibilty Mar 21, 2019
integration
scripts debug CI issue Mar 21, 2019
.gitignore add benchmark, support profiling, disable gc Oct 25, 2018
.travis.yml
LICENSE
README.md add version to gobin -m -run example Mar 21, 2019
appveyor.yml remove go 1.10 from ci matrix and set module mode explicitly in tests Oct 11, 2018
benchmark_test.go use v6 import path for go module v2+ compatibilty Mar 21, 2019
generated_fakes_test.go use v6 import path for go module v2+ compatibilty Mar 21, 2019
go.mod
go.sum
main.go use v6 import path for go module v2+ compatibilty Mar 21, 2019

README.md

counterfeiter Build Status Build status

When writing unit-tests for an object, it is often useful to have fake implementations of the object's collaborators. In go, such fake implementations cannot be generated automatically at runtime, and writing them by hand can be quite arduous.

counterfeiter allows you to simply generate test doubles for a given interface.

Supported Versions Of go

counterfeiter follows the support policy of go itself:

Each major Go release is supported until there are two newer major releases. For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was supported until the Go 1.8 release. We fix critical problems, including critical security problems, in supported releases as needed by issuing minor revisions (for example, Go 1.6.1, Go 1.6.2, and so on).

If you are having problems with counterfieter and are not using a supported version of go, please update to use a supported version of go before opening an issue.

Using counterfeiter

We recommend you use go modules when working with counterfeiter.

Typically, counterfeiter is used in go generate directives. It can be frustrating when you change your interface declaration and suddenly all of your generated code is suddenly out-of-date. The best practice here is to use the go generate command to make it easier to keep your test doubles up to date.

Step 1 - Install gobin

gobin is used to execute a binary by specifying a package path. This allows you to run a specific version of a tool.

GO111MODULE=off go get -u github.com/myitcv/gobin

Step 2 - Create tools.go

You can take a dependency on tools by creating a tools.go file, as described in How can I track tool dependencies for a module?. This ensures that everyone working with your module is using the same version of each tool you use.

$ cat tools/tools.go
// +build tools

package tools

import (
	_ "github.com/maxbrunsfeld/counterfeiter/v6"
)

// This file imports packages that are used when running go generate, or used
// during the development process but not otherwise depended on by built code.

Step 3 - Add go generate Directives

You can add directives right next to your interface definitions (or not), in any .go file in your module.

$ cat myinterface.go
package foo

//go:generate gobin -m -run github.com/maxbrunsfeld/counterfeiter/v6 . MySpecialInterface

type MySpecialInterface interface {
	DoThings(string, uint64) (int, error)
}
$ go generate ./...
Writing `FakeMySpecialInterface` to `foofakes/fake_my_special_interface.go`... Done

Step 4 - Run go generate

You can run go generate in the directory with your directive, or in the root of your module (to ensure you generate for all packages in your module):

go generate ./...

Invoking counterfeiter from the shell

You can use the following command to invoke counterfeiter from within a go module:

gobin -m -run github.com/maxbrunsfeld/counterfeiter/v6

USAGE
	counterfeiter
		[-o <output-path>] [-p] [--fake-name <fake-name>]
		[<source-path>] <interface> [-]

Installing counterfeiter to $GOPATH/bin

This is unnecessary if you're using the approach described above, but does allow you to invoke counterfeiter in your shell outside of a module:

$ GO111MODULE=off go get -u github.com/maxbrunsfeld/counterfeiter
$ counterfeiter

USAGE
	counterfeiter
		[-o <output-path>] [-p] [--fake-name <fake-name>]
		[<source-path>] <interface> [-]

Generating Test Doubles

Given a path to a package and an interface name, you can generate a test double.

$ cat path/to/foo/file.go
package foo

type MySpecialInterface interface {
		DoThings(string, uint64) (int, error)
}
$ gobin -m -run github.com/maxbrunsfeld/counterfeiter/v6 path/to/foo MySpecialInterface
Wrote `FakeMySpecialInterface` to `path/to/foo/foofakes/fake_my_special_interface.go`

Using Test Doubles In Your Tests

Instantiate fakes`:

import "my-repo/path/to/foo/foofakes"

var fake = &foofakes.FakeMySpecialInterface{}

Fakes record the arguments they were called with:

fake.DoThings("stuff", 5)

Expect(fake.DoThingsCallCount()).To(Equal(1))

str, num := fake.DoThingsArgsForCall(0)
Expect(str).To(Equal("stuff"))
Expect(num).To(Equal(uint64(5)))

You can stub their return values:

fake.DoThingsReturns(3, errors.New("the-error"))

num, err := fake.DoThings("stuff", 5)
Expect(num).To(Equal(3))
Expect(err).To(Equal(errors.New("the-error")))

For more examples of using the counterfeiter API, look at some of the provided examples.

Running The Tests For counterfeiter

If you want to run the tests for counterfeiter (perhaps, because you want to contribute a PR), all you have to do is run scripts/ci.sh.

Contributions

So you want to contribute to counterfeiter! That's great, here's exactly what you should do:

  • open a new github issue, describing your problem, or use case
  • help us understand how you want to fix or extend counterfeiter
  • write one or more unit tests for the behavior you want
  • write the simplest code you can for the feature you're working on
  • try to find any opportunities to refactor
  • avoid writing code that isn't covered by unit tests

counterfeiter has a few high level goals for contributors to keep in mind

  • keep unit-level test coverage as high as possible
  • keep main.go as simple as possible
  • avoid making the command line options any more complicated
  • avoid making the internals of counterfeiter any more complicated

If you have any questions about how to contribute, rest assured that @tjarratt and other maintainers will work with you to ensure we make counterfeiter better, together. This project has largely been maintained by the community, and we greatly appreciate any PR (whether big or small).

License

counterfeiter is MIT-licensed.

You can’t perform that action at this time.