maxbrunsfeld/counterfeiter
GitHub: maxbrunsfeld/counterfeiter
Stars: 1133 | Forks: 100
# `counterfeiter` [](https://github.com/maxbrunsfeld/counterfeiter/actions/workflows/go.yml) [](https://goreportcard.com/report/github.com/maxbrunsfeld/counterfeiter/v6) [](https://godoc.org/github.com/maxbrunsfeld/counterfeiter/v6)
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`
If you are having problems with `counterfeiter` and are not using a supported version of go, please update to use a supported version of go before opening an issue.
### Using `counterfeiter`
⚠️ Please use [`go modules`](https://blog.golang.org/using-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](https://blog.golang.org/generate) to make it easier to keep your test doubles up to date.
#### Step 1 - Add `counterfeiter` as a tool dependency
Establish a tool dependency on counterfeiter by running the following command:
go get -tool github.com/maxbrunsfeld/counterfeiter/v6
#### Step 2a - 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 go tool counterfeiter . MySpecialInterface
type MySpecialInterface interface {
DoThings(string, uint64) (int, error)
}
$ go generate ./...
Writing `FakeMySpecialInterface` to `foofakes/fake_my_special_interface.go`... Done
#### Step 2b - Add `counterfeiter:generate` Directives
If you plan to have many directives in a single package, consider using this
option, as it will speed things up considerably. You can add directives right
next to your interface definitions (or not), in any `.go` file in your module.
$ cat myinterface.go
package foo
// You only need **one** of these per package!
//go:generate go tool counterfeiter -generate
// You will add lots of directives like these in the same package...
//counterfeiter:generate . MySpecialInterface
type MySpecialInterface interface {
DoThings(string, uint64) (int, error)
}
// Like this...
//counterfeiter:generate . MyOtherInterface
type MyOtherInterface interface {
DoOtherThings(string, uint64) (int, error)
}
$ go generate ./...
Writing `FakeMySpecialInterface` to `foofakes/fake_my_special_interface.go`... Done
Writing `FakeMyOtherInterface` to `foofakes/fake_my_other_interface.go`... Done
#### Step 3 - 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:
$ go tool counterfeiter
USAGE
counterfeiter
[-generate>] [-o ] [-p] [--fake-name ]
[-header ]
[] [-]
#### 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:
$ go install github.com/maxbrunsfeld/counterfeiter/v6
$ ~/go/bin/counterfeiter
USAGE
counterfeiter
[-generate>] [-o ] [-p] [--fake-name ]
[-header ]
[] [-]
### 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)
}
$ go tool counterfeiter 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](https://github.com/maxbrunsfeld/counterfeiter/blob/master/generated_fakes_test.go).
### Generating Test Doubles For Third Party Interfaces
For third party interfaces, you can specify the interface using the alternative syntax `.`, for example:
$ go tool counterfeiter github.com/go-redis/redis.Pipeliner
### 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
- 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
### License
`counterfeiter` is MIT-licensed.
标签:EVTX分析