ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ## <span style="font-size:15px">**一、说明**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gomonkey 是golang的一款打桩框架,目标是让用户在单元测试中低成本的完成打桩,从而将精力聚焦于业务功能的开发。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GitHub地址:`https://github.com/agiledragon` ## <span style="font-size:15px">**二、常用法**</span> ### <span style="font-size:15px">**1、为函数打桩**</span> ``` func ApplyFunc(target, double interface{}) *Patches ``` 示例: ``` package util import ( "common/validator" ) type Calculator interface { Add(a, b int) int } type MyCalculator struct{} func (c *MyCalculator) Add(a, b int) int { if err := validator.Validator("verify.json", a); err != nil { return 0 } return a + b } ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在Add方法中,存在调用外部函数Validator进行参数校验,当校验不通过时,返回0。可通过ApplyFunc方法mock掉外部函数的返回值。 ``` func TestAddByGoMonkey(t *testing.T) { m := &MyCalculator{} mockValidator := gomonkey.ApplyFunc(validator.Validator, func(schemaPath string, checkValue interface{}) error { return errors.New("invalid") }) defer func() { mockValidator.Reset() }() if !assert.EqualValues(t, 0, m.Add(1, 2)) { t.Fail() } } ``` ### <span style="font-size:15px">**2、为函数变量打桩**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;函数变量是一种特殊的变量类型,可以用来存储函数的引用。它们可以像普通变量一样被声明、赋值和调用。 ``` func ApplyFuncVar(target, double interface{}) *Patches ``` ``` package util import ( "common/validator" ) type Calculator interface { Subtract(a, b int) int } type MyCalculator struct{} // 定义一个函数变量subtract,接受两个int类型的参数,并返回一个int类型的结果 var subtract = func(a, b int) int { return a - b } func (c *MyCalculator) Subtract(a, b int) int { return subtract(a, b) } ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用ApplyFuncVar方法mock函数遍历subtract返回值为2 ``` func TestSubtractByGoMonkey(t *testing.T) { m := &MyCalculator{} mockFuncVar := gomonkey.ApplyFuncVar(&subtract, func(a, b int) int { return 2 }) defer func() { mockFuncVar.Reset() }() if !assert.EqualValues(t, 2, m.Subtract(3, 2)) { t.Fail() } } ``` ### <span style="font-size:15px">**3、为全局变量打桩**</span> ``` func ApplyGlobalVar(target, double interface{}) *Patches ``` 示例: ``` package util import ( "common/validator" ) type Calculator interface { Add(a, b int) int } type MyCalculator struct{} var num = 10 func (c *MyCalculator) Add(a, b int) int { if err := validator.Validator("verify.json", a); err != nil { return num } return a + b } ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用ApplyGlobalVar函数mock掉全局变量的值 ``` func TestAddByGoMonkey(t *testing.T) { m := &MyCalculator{} mockGlobalVar := gomonkey.ApplyGlobalVar(&num, 20) mockValidator := gomonkey.ApplyFunc(validator.Validator, func(schemaPath string, checkValue interface{}) error { return errors.New("invalid") }) defer func() { mockValidator.Reset() mockGlobalVar.Reset() }() if !assert.EqualValues(t, 20, m.Add(1, 2)) { t.Fail() } } ``` ### <span style="font-size:15px">**4、为成员方法打桩**</span> ``` func ApplyMethod(target interface{}, methodName string, double interface{}) *Patches ``` 示例: ### <span style="font-size:15px">**4、为成员接口打桩**</span> 示例: ``` // calulator.go package util import ( "github.com/sirupsen/logrus" "common/validator" ) type Calculator interface { Subtract(a, b int) int } type MyCalculator struct{} var subtract = func(a, b int) int { return a - b } func (c *MyCalculator) Subtract(a, b int) int { result := subtract(a, b) rest := validator.NewIRest() return rest.RestOne() } ``` ``` // rest.go package validator type MyRest struct{} type ( IRest interface { RestOne() int } Irest struct{} ) func (i *Irest) RestOne() int { return 7 } func NewIRest() IRest { return &Irest{} } ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;calulator.go的Subtract方法,实例化了rest.go的interface,并调用了RestOne接口。使用ApplyMethod对Irest的成员接口RestOne进行mock,使其返回4, ``` func TestSubtractByGoMonkey(t *testing.T) { m := &MyCalculator{} restMock := gomonkey.ApplyMethod(reflect.TypeOf(validator.NewIRest()), "RestOne", func(_ *validator.Irest) int { return 4 }, ) defer func() { restMock.Reset() }() if !assert.EqualValues(t, 4, m.Subtract(3, 2)) { t.Fail() } } === RUN TestSubtractByGoMonkey INFO[0000] result:1 INFO[0000] RestOne:4 --- PASS: TestSubtractByGoMonkey2 (0.00s) PASS ok sangfor.com/xdr/xlink/common/util 0.045s ```