English | 中文
Mockey 是一款简单易用的 Golang 打桩工具库,能够快速方便地进行函数、变量的 mock,目前在字节跳动各业务的单元测试编写中应用较为广泛,其底层是通过运行时改写函数指令实现的猴子补丁(Monkey Patch)
go get github.com/bytedance/mockey@latest
import (
"fmt"
"testing"
. "github.com/bytedance/mockey"
. "github.com/smartystreets/goconvey/convey"
)
func Foo(in string) string {
return in
}
type A struct{}
func (a A) Foo(in string) string { return in }
var Bar = 0
func TestMockXXX(t *testing.T) {
PatchConvey("TestMockXXX", t, func() {
Mock(Foo).Return("c").Build() // mock函数
Mock(A.Foo).Return("c").Build() // mock方法
MockValue(&Bar).To(1) // mock变量
So(Foo("a"), ShouldEqual, "c") // 断言`Foo`成功mock
So(new(A).Foo("b"), ShouldEqual, "c") // 断言`A.Foo`成功mock
So(Bar, ShouldEqual, 1) // 断言`Bar`成功mock
})
// `PatchConvey`外自动释放mock
fmt.Println(Foo("a")) // a
fmt.Println(new(A).Foo("b")) // b
fmt.Println(Bar) // 0
}
- mock 函数和方法
- 基础功能
- 普通/可变参数函数
- 普通/可变参数方法
- 嵌套结构体方法
- 私有类型的导出方法(不同包下)
- 高级功能
- mock 后执行原函数
- goroutine 条件过滤
- 增量改变 mock 行为
- 获取原函数执行次数
- 获取 mock 函数执行次数
- 基础功能
- mock 变量
- 普通变量
- 函数变量
- Mac OS(Darwin)
- Linux
- Windows
- AMD64
- ARM64
- Go 1.13+
Mockey 基于Apache License 2.0 许可证,其依赖的三方组件的开源许可见 Licenses
Go 1.23 编译错误 "link: github.com/bytedance/mockey/internal/monkey/common: invalid reference to runtime.sysAllocOS"
?
增加编译参数 -ldflags=-checklinkname=0
- 命令行:
go test -gcflags="all=-l -N" -v ./...
- Goland:在 运行/调试配置 > Go工具实参 对话框中填写
-gcflags="all=-l -N"
- 未禁用内联或者编译优化:可以尝试使用 debug 模式,如果能跑过则说明是该问题,请转到 FAQ 相关章节
- 未调用
Build()
方法:mock 函数时漏写了.Build()
,导致没有任何实际效果产生 - 目标函数不完全匹配:
func TestXXX(t *testing.T) {
Mock((*A).Foo).Return("c").Build()
fmt.Println(A{}.Foo("a")) // 走入原函数,目标函数应该是A.Foo
a := A{}
Mock(a.Foo).Return("c").Build()
fmt.Println(a.Foo("a")) // 走入原函数,目标函数应该是A.Foo或者使用工具函数GetMethod从a中获取
}
- 目标函数在其他协程里执行:
func TestXXX(t *testing.T) {
PatchConvey("TestXXX", t, func() {
Mock(Foo).Return("c").Build()
go Foo("a") // 执行Foo的时机不定
})
// 主协程走到这里时相关mock已经被PatchConvey释放,如果Foo先于此执行则mock成功,否则失败
fmt.Println("over")
time.Sleep(time.Second)
}