Moq 项目介绍
Moq 是一个专为 Go 语言开发者设计的接口模拟工具,用于生成可在测试代码中使用的接口模拟结构体。
什么是 Moq?
Moq 工具可以从任意接口生成一个结构体,该结构体可以在测试代码中用作接口的模拟对象。当开发者需要测试某一个接口实现而又不希望真实实现的副作用时,这个工具就显得尤为重要。通过生成的模拟结构体,开发者可以在测试中模拟接口的行为,便于测试用例的编写和测试的控制。
安装方法
要安装 Moq 的最新发布版本,可通过以下命令:
$ go install github.com/matryer/moq@latest
注意,安装时需要至少 Go 语言版本 1.18 如果使用较低版本的 Go,可以下载 Moq 发布的预构建二进制文件。
使用指南
Moq 在命令行中使用,基本命令格式如下:
moq [选项] source-dir interface [interface2 [interface3 [...]]]
以下是一些常用选项及其功能:
-out string
:指定输出文件,默认为标准输出。-pkg string
:指定包名,默认会自动推断。-rm
:如果输出文件已存在,先移除。-stub
:当没有提供模拟实现时返回零值,避免 panic。-with-resets
:生成重置方法以便于重置对模拟对象的调用。
source-dir
是目标接口源代码所在的目录,要提供目录路径而非 Go 包的导入语句。
命令行示例如下:
$ moq -out mocks_test.go . MyInterface
在代码中使用(用于 go generate):
package my
//go:generate moq -out myinterface_moq_test.go . MyInterface
type MyInterface interface {
Method1() error
Method2(i int)
}
然后在你的包中运行 go generate
。
使用场景
接口模拟是一种优雅的单元测试方式,允许开发者轻松控制被模拟对象的行为。用户可以在测试代码中声明每个方法的函数字段,这使得编写测试用例更加灵活。
在下面的示例中,Moq 生成了 EmailSenderMock
类型:
func TestCompleteSignup(t *testing.T) {
var sentTo string
mockedEmailSender = &EmailSenderMock{
SendFunc: func(to, subject, body string) error {
sentTo = to
return nil
},
}
CompleteSignUp("me@email.com", mockedEmailSender)
callsToSend := len(mockedEmailSender.SendCalls())
if callsToSend != 1 {
t.Errorf("Send was called %d times", callsToSend)
}
if sentTo != "me@email.com" {
t.Errorf("unexpected recipient: %s", sentTo)
}
}
func CompleteSignUp(to string, sender EmailSender) {
// TODO: this
}
在这种模拟结构体中,每个方法会调用相关的函数字段。
小贴士
- 将模拟逻辑保持在使用它的测试中。
- 只模拟所需的字段。
- 如果调用了一个空的函数会导致 panic。
- 为了更好的体验,在接口中命名参数。
- 在测试函数中使用闭包变量来捕获方法调用的细节。
- 使用
.MethodCalls()
来跟踪调用。 - 使用
.ResetCalls()
在个人模拟对象的上下文中重置调用。 - 使用
go:generate
命令调用moq
。 - 如果 Moq 出现
go/format
错误,表明生成的代码无效。可以使用-fmt noop
来打印未格式化的源代码,以帮助调试。
Moq 项目及所有代码都依照 MIT 许可证发布,由 Mat Ryer 和 David Hernandez 创建,项目中结合了 Ernesto Jimenez 的一些想法,并得到了众多贡献者的帮助和完善。Moq 的 logo 由 Chris Ryer 创作,并根据 Creative Commons 署名 3.0 许可证发布。