Go

counterfeiter介绍及使用

Posted by TopJohn on 2019-10-11
本文总阅读量

介绍

counterfeiter是一种go预言的自包含的,类型安全的测试工具。

Github地址:https://github.com/maxbrunsfeld/counterfeiter

在go语言中,当我们需要为一个对象编写单元测试的时候,通常使用一个Mock的对象相关的写作者将会非常有用。在go语言中,无法在运行时自动生成此类伪造的实现,并且手工编写它们将非常艰巨。

counterfeiter允许你简单地为指定接口生成测试实现对象。

支持的go版本:

counterfeiter遵循go自身支持的政策:

支持每个主要的Go版本,直到有两个新的主要版本为止。例如,直到Go 1.7发行版才支持Go 1.5,直到Go 1.8发行版才支持Go 1.6。我们会通过发布次要修订(例如,Go 1.6.1,Go 1.6.2等)在受支持的发行版中修复包括关键安全问题在内的关键问题。

如果您在使用counterfeitergo时遇到问题,但未使用支持的go语言版本,请先更新以使用go的受支持版本,然后再打开问题。

使用 counterfeiter

我们建议您go modules使用counterfeiter。

通常,counterfeiter在go generate指令中使用。当您更改接口声明并且突然所有生成的代码突然过时时,这可能会令人沮丧。此处的最佳做法是使用go generate命令使测试更加容易地保持最新状态。

第1步-创建 tools.go

您可以通过创建tools.go文件来获得对工具的依赖,如如何跟踪模块的工具依赖关系中所述。这样可以确保使用模块的每个人都使用与您使用的每个工具相同的版本。

1
$ cat tools/tools.go
1
2
3
4
5
6
7
8
9
10
// +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.

步骤2a-添加go:generate指令

您可以在模块中的任何.go文件中在接口定义旁边添加指令。

1
$ cat myinterface.go
1
2
3
4
5
6
7
package foo

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

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

步骤2b-添加counterfeiter:generate指令

如果您打算在一个软件包中包含多个指令,请考虑使用此选项。您可以.go在模块中的任何文件中在接口定义旁边添加指令。

1
$ cat myinterface.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package foo

// You only need **one** of these per package!
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -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)
}

第3步-运行 go generate

您可以go generate使用指令在目录中运行,也可以在模块的根目录中运行(以确保为模块中的所有软件包生成):

1
$ go generate ./...

counterfeiter从shell调用

您可以从go模块中使用以下命令调用counterfeiter:

1
2
3
4
5
6
$ go run github.com/maxbrunsfeld/counterfeiter/v6

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

安装counterfeiter到$GOPATH/bin

如果您正在使用上述方法,则这是不必要的,但确实允许您counterfeiter在模块外部的Shell中调用:

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

生成测试实例

给定包的路径和接口名称,您可以生成一个测试实例。

1
$ cat path/to/foo/file.go
1
2
3
4
5
package foo

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

在测试中使用测试实例

实例化:

1
2
3
import "my-repo/path/to/foo/foofakes"

var fake = &foofakes.FakeMySpecialInterface{}

实例记录了调用时的参数:

1
2
3
4
5
6
7
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)))

你也可以记录返回值:

1
2
3
4
5
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")))

有关使用counterfeiterAPI的更多示例,请参阅提供的一些示例

为第三方接口生成测试用例

对于第三方接口,可以使用替代语法指定接口.,例如:

1
$ go run github.com/maxbrunsfeld/counterfeiter/v6 github.com/go-redis/redis.Pipeliner

counterfeiter运行测试

如果您要运行测试counterfeiter(也许是因为您想贡献PR),则只需运行scripts/ci.sh

AwesomeBlockchain