Mockey 是一款简单易用的 Golang 打桩工具库,能够快速方便地进行函数、变量的 mock,目前在字节跳动各业务的单元测试编写中应用较为广泛,其底层是通过运行时改写函数指令实现的猴子补丁(Monkey Patch)
具体介绍可以看官方文档
使用方法
foo/mocki.go
foo/foobar_test.go
foo/bar/foobar.go
package foo
import (
"reflect"
"github.com/bytedance/mockey"
)
func MockI(target any, opts ...any) *mockey.MockBuilder {
if len(opts) == 0 {
return mockey.Mock(target)
}
methodName := opts[0].(string)
v := reflect.TypeOf(target)
method, _ := v.MethodByName(methodName)
fn := method.Func.Interface()
return mockey.Mock(fn)
}
package bar
type BarInterface interface {
Foo() string
Bar() string
}
type privateStruct struct {
}
func (o privateStruct) Foo() string {
return ""
}
func (o *privateStruct) Bar() string {
return ""
}
func NewPrivateStruct() BarInterface {
return &privateStruct{}
}
type PublicStruct struct {
}
func (o PublicStruct) Foo() string {
return ""
}
func (o *PublicStruct) Bar() string {
return ""
}
package foo
import (
"testing"
"happy-fox-data-library-service/common/foo/bar"
. "github.com/bytedance/mockey"
. "github.com/smartystreets/goconvey/convey"
)
func shr(n int, position int) int {
return n >> position
}
func TestSHR(t *testing.T) {
PatchConvey("Test shift logical right", t, func() {
PatchConvey("不mock", func() {
So(shr(1, 2), ShouldEqual, 0)
So(shr(2, 2), ShouldEqual, 0)
So(shr(3, 2), ShouldEqual, 0)
So(shr(4, 2), ShouldEqual, 1)
})
PatchConvey("mock", func() {
Mock(shr).Return(10).Build()
So(shr(1, 2), ShouldEqual, 10)
})
})
}
func TestMockPublicStructMethods(t *testing.T) {
PatchConvey("Test mock public struct methods", t, func() {
PatchConvey("非指针类型receiver", func() {
o := bar.PublicStruct{}
Mock(bar.PublicStruct.Foo).Return("hello foo").Build()
So(o.Foo(), ShouldEqual, "hello foo")
})
PatchConvey("指针类型receiver", func() {
o := bar.PublicStruct{}
Mock((*bar.PublicStruct).Bar).Return("hello bar").Build()
So(o.Bar(), ShouldEqual, "hello bar")
})
})
}
func TestMockPrivateStructMethods(t *testing.T) {
PatchConvey("Test mock private struct methods", t, func() {
PatchConvey("非指针类型receiver", func() {
o := bar.NewPrivateStruct()
MockI(o, "Foo").Return("hello foo").Build()
So(o.Foo(), ShouldEqual, "hello foo")
})
PatchConvey("指针类型receiver", func() {
o := bar.NewPrivateStruct()
MockI(o, "Bar").Return("hello bar").Build()
So(o.Bar(), ShouldEqual, "hello bar")
})
})
}