gomonkey测试框架

1.说明

gomonkey 是 golang 的一款打桩框架,目标是让用户在单元测试中低成本的完成打桩,从而将精力聚焦于业务功能的开发。

参考文档:https://blog.csdn.net/weixin_36163504/article/details/112583704

2.github仓库

https://github.com/agiledragon/gomonkey

3.用法参考

参考:https://blog.csdn.net/u013276277/article/details/104993370

4.使用场景

4.1为函数打桩

注意:下面的文件进行测试时,需要加上参数-gcflags=-l。 原因参考:https://www.jianshu.com/p/19089baf79ca

文件:isConfigFileContain.go

package funmonkey
 
import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"
)
 
// 判断/opt/container/config.properties文件中是否包含str字符串
func isConfigFileContain(str string) (bool, error) {
    defer func() {
        if err := recover(); err != nil {
            fmt.Printf("错误:%v\n", err)
        }
    }()
 
    file, err := os.Open("/opt/container/config.properties")
    if err != nil {
        fmt.Printf("open错误:%v\n", err)
        return false, err
    }
    defer file.Close()
 
    content, err := ioutil.ReadAll(file)
    if err != nil {
        fmt.Printf("ReadAll错误:%v\n", err)
        return false, err
    }
    return strings.Contains(string(content), str), err
}

文件:isConfigFileContain_test.go

package funmonkey
 
import (
    "fmt"
    "io"
    "io/ioutil"
    "os"
    "testing"
    "github.com/agiledragon/gomonkey"
    // "github.com/stretchr/testify/assert"
    . "github.com/smartystreets/goconvey/convey"
)
 
// 用普通的方式测试会找不到文件
// func TestIsConfigFileContain(t *testing.T) {
//  ast := assert.New(t)
//  ast.True(isConfigFileContain("test"))
// }
 
// 以下用monkey patch进行测试
func TestIsConfigFileContain(t *testing.T) {
    Convey("TestIsConfigFileContain", t, func() {
 
        //下面正常逻辑
        Convey("return nil", func() {
            //open返回nil
            patches := gomonkey.ApplyFunc(os.Open, func(_ string) (*os.File, error) {
                return &os.File{}, nil
            })
            defer patches.Reset()
            //readAll返回nil
            patches.ApplyFunc(ioutil.ReadAll, func(_ io.Reader) ([]byte, error) {
                return nil, nil
            })
            flag, err := isConfigFileContain("str")
            So(err, ShouldBeNil)
            So(flag, ShouldEqual, false)
        })
        //返回错误
        Convey("return error when os.open error", func() {
            //open返回error
            patches := gomonkey.ApplyFunc(os.Open, func(str string) (*os.File, error) {
                return nil, fmt.Errorf("os.open panic")
            })
            defer patches.Reset()
            flag, err := isConfigFileContain("str")
            So(err, ShouldNotBeNil)
            So(flag, ShouldEqual, false)
        })
        //返回错误
        Convey("should be return error when ioutil.ReadAll error", func() {
            patches := gomonkey.ApplyFunc(os.Open, func(str string) (*os.File, error) {
                return nil, nil
            })
            defer patches.Reset()
            //readAll返回error
            patches.ApplyFunc(ioutil.ReadAll, func(io.Reader) ([]byte, error) {
                return nil, fmt.Errorf("ioutil.ReadAll panic")
            })
            flag, err := isConfigFileContain("str")
            So(err, ShouldNotBeNil)
            So(flag, ShouldEqual, false)
        })
    })
}

4.2为方法打桩

参考:https://blog.csdn.net/u013276277/article/details/104993370

4.3为变量打桩

文件:one.go

package main
 
import (
    "fmt"
 
    "xorm.io/xorm"
)
 
type Mode struct {
    Id   int64
    Type string
}
type Orm struct {
    *xorm.Engine
}
 
var GDB *Orm
 
func Init() {
    conn := "root" + ":" + "eisoo.com123" + "@tcp(" + "10.2.33.180" + ":" +
        "3306" + ")/" + "metadata" + "?charset=" + "utf8"
    //新建一个连接
    engine := new(xorm.Engine)
    engine, err := xorm.NewEngine("mysql", conn)
    if err != nil {
        fmt.Println(err)
        return
    }
    //开辟空间
    GDB = new(Orm)
    GDB.Engine = engine
}
 
func main() {
    var mode []Mode
    //使用全局变量进行查询
    GDB.Engine.Where("select").Find(&mode)
    fmt.Println(mode)
}

文件:one_test.go

package main
 
import (
    "fmt"
 
    "xorm.io/xorm"
)
 
type Mode struct {
    Id   int64
    Type string
}
type Orm struct {
    *xorm.Engine
}
 
var GDB *Orm
 
func Init() {
    conn := "root" + ":" + "123456" + "@tcp(" + "10.2.33.184" + ":" +
        "3306" + ")/" + "metadata" + "?charset=" + "utf8"
    //新建一个连接
    engine := new(xorm.Engine)
    engine, err := xorm.NewEngine("mysql", conn)
    if err != nil {
        fmt.Println(err)
        return
    }
    //开辟空间
    GDB = new(Orm)
    GDB.Engine = engine
}
 
func main() {
    var mode []Mode
    //使用全局变量进行查询
    GDB.Engine.Where("select").Find(&mode)
    fmt.Println(mode)
}

5.小结

gomonkey能够mock大部分的函数、方法、变量等内容,能够满足大部分mock需求。但是对于需要访问服务器、访问数据库等,就不太好用了。后面将介绍一种针对服务器访问的测试框架,httptest。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值