# 使用gomonkey单元测试进行单元测试用例编写
## 背景介绍
* gomonkey是一款Go语言的打桩框架,目标是让用户在单元测试中低成本的完成打桩,从而将精力聚焦于业务功能的开发
* 实现对函数,变量,结构体成员方法进行mock模拟。
* 实例包括对整个HTTP请求和方法的模拟(构造整个请求过程,构造HTTP请求,构造HTTP响应,构造HTTP响应体,数据库查询等)
## 安装
go get -u github.com/agiledragon/gomonkey
## 对基础函数进行打桩
```go
func RequestHarbor404(path string, method string, data interface{}, info map[string]interface{}, value interface{}) (err error) {
return errors.New("404")
}
// 对client.HttpRequest进行mock模拟
// 模拟返回404
patch := gomonkey.ApplyFunc(client.HttpRequest, client.RequestHarbor404)
defer patch.Reset()
对成员方法进行打桩
// 模拟查询数据库的 RepositoriesDao.Queryrepositories方法
// 模拟方法进行构造数据库的查询结果集,模拟查询异常等
var respDao *service.RepositoriesDao
patch2 := gomonkey.ApplyMethod(reflect.TypeOf(respDao), "Queryrepositories",
func(_ *service.RepositoriesDao, project, repositoriesName string) (po []*model.Repositories, err error) {
return nil, errors.New("")
})
defer patch2.Reset()
模拟构造一个http请求对象
// 手动创建一个Context对象 构造NewRequest和ResponseWriter
uri, _ := url.Parse("url")
request := httptest.NewRequest("GET", uri.String(), nil)
write := httptest.NewRecorder()
// 手动创建一个Context对象
ctx := context.NewContext(app)
ctx.BeginRequest(write, request)
ctx.Request().Header.Add("Gap-One-Token", "one_token=devopsone")
构造一个client.Db对象并对Transaction方法进行模拟
// 构造一个client.Db对象并对Transaction方法进行模拟
mockDB, _, _ := sqlmock.New()
client.Db, _ = gorm.Open(gormMysql.New(gormMysql.Config{
Conn: mockDB,
// SELECT VERSION;
SkipInitializeWithVersion: true,
}), &gorm.Config{
// 你 mock DB 不需要 ping
DisableAutomaticPing: true,
// 这个是什么呢?
SkipDefaultTransaction: true,
})
// 构造client.Db的Transaction方法
patch4 := gomonkey.ApplyMethod(reflect.TypeOf(client.Db), "Transaction",
func(_ *gorm.DB, fc func(tx *gorm.DB) error, opts ...*sql.TxOptions) (err error) {
err = fc(client.Db)
return
})
defer patch4.Reset()
执行命令(在test文件当前目录下执行)
- 直接控制台输出: go test -v -covermode=count -coverprofile=cover.out -gcflags "all=-N -l"
- 导出测试报告: go test -v -covermode=count -coverprofile=cover.out -gcflags "all=-N -l" && go tool cover -html=cover.out