maxbrunsfeld/counterfeiter
GitHub: maxbrunsfeld/counterfeiter
counterfeiter 是一款 Go 语言的测试 double 生成工具,通过自动为接口生成类型安全的假实现来简化单元测试中 mock 的编写工作。
Stars: 1136 | Forks: 101
# `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)
在为对象编写单元测试时,拥有该对象协作者的 fake 实现通常非常有用。在 go 中,此类 fake 实现无法在 runtime 自动生成,并且手动编写它们可能相当繁琐。
`counterfeiter` 允许你轻松地为给定 interface 生成 test double。
### 支持的 `go` 版本
`counterfeiter` 遵循 [`go` 自身的支持策略](https://golang.org/doc/devel/release.html#policy):
如果你在使用 `counterfeiter` 时遇到问题,并且没有使用受支持的 go 版本,请在提交 issue 之前更新到受支持的 go 版本。
### 使用 `counterfeiter`
⚠️ 使用 counterfeiter 时,请使用 [`go modules`](https://blog.golang.org/using-go-modules)。
通常,`counterfeiter` 用于 `go generate` 指令中。当你修改了 interface 定义,突然发现所有生成的代码瞬间过期时,这可能会让人感到沮丧。这里的最佳实践是使用 [`go generate` 命令](https://blog.golang.org/generate),以便更轻松地保持你的 test double 为最新状态。
⚠️ 如果你使用的是 go 1.23 或更早版本,请参阅[本 README 的旧版本](https://github.com/maxbrunsfeld/counterfeiter/blob/e39cbe6aaa94a0b6718cf3d413cd5319c3a1f6fa/README.md#using-counterfeiter),因为以下说明假设使用的是 go 1.24(添加了 `go tool` 支持)及更高版本。
#### 步骤 1 - 将 `counterfeiter` 添加为工具依赖
运行以下命令,建立对 counterfeiter 的工具依赖:
```
go get -tool github.com/maxbrunsfeld/counterfeiter/v6
```
#### 步骤 2a - 添加 `go:generate` 指令
你可以在 module 中的任何 `.go` 文件里,直接在 interface 定义旁边(或者随意位置)添加指令。
```
$ 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
```
#### 步骤 2b - 添加 `counterfeiter:generate` 指令
如果你打算在单个 package 中使用许多指令,请考虑使用此选项,因为它会显著加快速度。你可以在 module 中的任何 `.go` 文件里,直接在 interface 定义旁边(或者随意位置)添加指令。
```
$ 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
```
#### 步骤 3 - 运行 `go generate`
你可以在包含指令的目录中运行 `go generate`,或者在 module 的根目录中运行(以确保为 module 中的所有 package 生成):
```
$ go generate ./...
```
#### 在 shell 中调用 `counterfeiter`
你可以使用以下命令在 go module 中调用 `counterfeiter`:
```
$ go tool counterfeiter
USAGE
counterfeiter
[-generate>] [-o ] [-p] [--fake-name ]
[-header ]
[] [-]
```
#### 将 `counterfeiter` 安装到 `$GOPATH/bin`
如果你使用的是上述方法,则无需此操作,但它确实允许你在 module _之外_ 的 shell 中调用 `counterfeiter`:
```
$ go install github.com/maxbrunsfeld/counterfeiter/v6
$ ~/go/bin/counterfeiter
USAGE
counterfeiter
[-generate>] [-o ] [-p] [--fake-name ]
[-header ]
[] [-]
```
### 生成 Test Double
给定一个指向 package 的路径和 interface 名称,你就可以生成一个 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`
```
### 在测试中使用 Test Double
实例化 fake:
```
import "my-repo/path/to/foo/foofakes"
var fake = &foofakes.FakeMySpecialInterface{}
```
Fake 会记录调用它们时所使用的参数:
```
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)))
```
你可以 stub 它们的返回值:
```
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")))
```
有关使用 `counterfeiter` API 的更多示例,请查看[提供的一些示例](https://github.com/maxbrunsfeld/counterfeiter/blob/master/generated_fakes_test.go)。
### 为第三方 Interface 生成 Test Double
对于第三方 interface,你可以使用替代语法 `.` 来指定 interface,例如:
```
$ go tool counterfeiter github.com/go-redis/redis.Pipeliner
```
### 运行 `counterfeiter` 的测试
如果你想运行 `counterfeiter` 的测试(可能是因为你想贡献一个 PR),你只需要运行 `scripts/ci.sh`。
### 许可证
`counterfeiter` 使用 MIT 许可证。
标签:EVTX分析, Go, Ruby工具, SOC Prime, 代码生成, 单元测试, 开发工具, 日志审计, 测试替身, 渗透测试工具