一。介绍
gomonkey 是 golang 的一款打桩框架,目标是让用户在单元测试中低成本的完成打桩,从而将精力聚焦于业务功能的开发。
实现原理《golang实现运行时替换函数体及其原理》
gomonkey支持的特性以及使用方法
- 支持为函数/ 接口打一个桩
- 支持为函数/ 接口打一个特定的桩序列
- 支持为成员方法打一个桩
- 支持为成员方法打一个特定的桩序列
- 支持为函数变量打一个桩
- 支持为函数变量打一个特定的桩序列
- 支持为全局变量打一个桩
注意:Reset方法用于删除桩, 注意使用defer将删除桩压栈。
方法 | 作用 | 函数使用说明 |
---|---|---|
ApplyFunc(target, double interface{} | 为函数/ 接口打一个桩 | target表示函数名,第二个参数表示桩函数。 |
ApplyFuncSeq(target interface{}, outputs []OutputCell) | 为函数/ 接口打一个特定的桩序列 | target表示函数名,第二个参数表示桩序列参数(返回值需序列)。 |
ApplyMethod(target reflect.Type, methodName string, double interface{}) | 为成员方法打一个桩 | target表示对象类型,对象的方法名,第三个参数表示桩函数。 |
ApplyMethodSeq(target reflect.Type, methodName string, outputs []OutputCell) | 为成员方法打一个特定的桩序列 | target表示对象类型,对象的方法名,第三个参数表示桩序列参数(返回值需序列)。 |
ApplyFuncVar(target, double interface{}) | 为函数变量打一个桩 | target表示函数变量,第二个参数表示桩函数。 |
ApplyFuncVarSeq(target interface{}, outputs []OutputCell) | 为函数变量打一个特定的桩序列 | target表示函数变量,第二个参数表示桩序列参数(返回值需序列)。 |
ApplyGlobalVar(target, double interface{}) | 为全局变量打一个桩 | target表示函数变量,第二个参数表示桩函数。 |
Reset() | 删除桩 |
二。 使用
代码语言:txt复制func Test_UserDao2(t *testing.T) {
Convey("Give test start", t, func() {
Convey("When ApplyFunc For Func", func() {
// 支持为函数打一个桩
want := "Replace SelectOne Return"
selectOnePatch := gomonkey.ApplyFunc(SelectOne, func(id string) string {
return want
})
defer selectOnePatch.Reset()
ret := SelectOne("1")
So(ret, ShouldEqual, want)
})
// 支持为函数打一个特定的桩序列
Convey("When ApplyFuncSeq For Func", func() {
want := []gomonkey.OutputCell{
{Values: gomonkey.Params{"1"}},
{Values: gomonkey.Params{"2"}},
{Values: gomonkey.Params{"3"}},
}
selectList := gomonkey.ApplyFuncSeq(SelectList, want)
defer selectList.Reset()
Convey("Then Test ApplyFuncSeq Patch", func() {
So(SelectList(), ShouldEqual, "1")
So(SelectList(), ShouldEqual, "2")
So(SelectList(), ShouldEqual, "3")
})
})
// 支持为成员方法打一个桩
Convey("When ApplyMethod For userDao Func", func() {
u := &userDao{}
updateF := gomonkey.ApplyMethod(reflect.TypeOf(u), "Update", func(_ *userDao, id, name, phoneNumber string) int64 {
fmt.Println(id, name, phoneNumber)
return 1
})
defer updateF.Reset()
Convey("Then Test ApplyMethod userDao Func Patch", func() {
So(u.Update("", "", ""), ShouldEqual, int64(1))
})
})
// 支持为全局变量打一个桩
num := 1
Convey("When ApplyGlobalVar", func() {
globalVar := gomonkey.ApplyGlobalVar(&num, 10)
defer globalVar.Reset()
Convey("Then Test ApplyGlobalVar Patch", func() {
So(num, ShouldEqual, int64(10))
})
})
// 定义函数变量f1, f2
f1 := func() string {
return "0"
}
f2 := func() string {
return "0"
}
// 支持为函数变量打桩
Convey("When ApplyFuncVarSeq", func() {
want := []gomonkey.OutputCell{
{Values: gomonkey.Params{"1"}},
{Values: gomonkey.Params{"2"}},
{Values: gomonkey.Params{"3"}},
}
// 支持为函数变量打一个特定的桩序列
funcVarSeq := gomonkey.ApplyFuncVarSeq(&f1, want)
defer funcVarSeq.Reset()
// 支持为函数变量打一个桩
objVar := gomonkey.ApplyFuncVar(&f2, func() string {
return "ggr"
})
defer objVar.Reset()
Convey("Then Test ApplyFuncVarSeq&ApplyFuncVar Patch", func() {
So(f1(), ShouldEqual, "1")
So(f1(), ShouldEqual, "2")
So(f1(), ShouldEqual, "3")
So(f2(), ShouldEqual, "ggr")
})
})
})
}
gomonkey是一款非常常用的打桩工具,务必学会使用。