学习go
多种测试工具
https://studygolang.com/articles/10124
https://www.jianshu.com/p/7349c7073aa5
https://geektutu.com/post/quick-gomock.html
单元测试
文件名以"_test"结尾,测试函数以Test开头
基准测试(benchmark)的参数是 *testing.B,TestMain 的参数是 testing.M 类型,普通测试testing.T
测试的框架之一Mockgen
mock测试前提是依赖注入,所以需要使用到接口,
看下面的接口,凡是使用到Execute(param []interface{})作为私有方法的,都是对接口的一种实现。
type KafkaExecutor interface {
//消息处理
//Execute(msg *sarama.ConsumerMessage)
Execute(param []interface{})
}
//使用接口作为入参
func Consume(config config.KafkaConfig, executor KafkaExecutor) {}
项目中的情况
原本不用baseDB入参的,现在相当于为了注入使用了
baseDB := &db.BaseDB{}
group, err := GetPageAddFiles(pa.AppId, flowKey, strconv.FormatInt(global.RunId, 10), pageVo.ContentTemplates, baseDB)
}
1,引用包
go get github.com/golang/mock/gomock
go install github.com/golang/mock/mockgen
找到对应的包,执行go build生成可执行文件mockgen.exe
cd D:\go\gopath\pkg\mod\github.com\golang\mock@v1.4.4\mockgen
go build
将包放在gopath/bin
如果你的工程中的第三方库统一放在vendor目录下,则需要拷贝一份gomock的代码到$GOPATH/src下,gomock的代码即github.com/golang/mock/gomock,这是因为mockgen命令运行时要在这个路径访问gomock
2,生成 db_mock.go
使用 mockgen 生成 db_mock.go。一般传递三个参数。包含需要被mock的接口得到源文件source,生成的目标文件destination,包名package
mockgen -source=db.go -destination=db_mock.go -package=main
1,加载包
go get github.com/golang/mock/gomock
go install github.com/golang/mock/mockgen
2,生成可执行程序
先找到已经加载好的包,如果是vendor,会在gopath的pkg路径,可以先去mod中找,然后go build生成程序
cd D:\go\gopath\pkg\mod\github.com\golang\mock@v1.4.4\mockgen
go build
这个时候会得到一个mockgen.exe可执行文件,将程序放在gopath的bin路径
然后在命令行执行mockgen查看是否可执行
3,生成mock
注意路径的写法,db_interface.go这里就必须先到对应的go文件的路径下才能执行,source源文件,destination目标文件,package目标文件所在的包
mockgen -source=db_interface.go -destination=db_interface_mock.go -package=db
接口
type MongoDB interface {
AddOne(db *mongo.Collection, ctx context.Context, data interface{}) error
FindMany(db *mongo.Collection, ctx context.Context, filter bson.M) ([]map[string]interface{}, error)
}
生成的mock
// Code generated by MockGen. DO NOT EDIT.
// Source: db_interface.go
// Package db is a generated GoMock package.
package mock
import (
context "context"
gomock "github.com/golang/mock/gomock"
bson "go.mongodb.org/mongo-driver/bson"
mongo "go.mongodb.org/mongo-driver/mongo"
reflect "reflect"
)
// MockMongoDB is a mock of MongoDB interface
type MockMongoDB struct {
ctrl *gomock.Controller
recorder *MockMongoDBMockRecorder
}
// MockMongoDBMockRecorder is the mock recorder for MockMongoDB
type MockMongoDBMockRecorder struct {
mock *MockMongoDB
}
// NewMockMongoDB creates a new mock instance
func NewMockMongoDB(ctrl *gomock.Controller) *MockMongoDB {
mock := &MockMongoDB{ctrl: ctrl}
mock.recorder = &MockMongoDBMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockMongoDB) EXPECT() *MockMongoDBMockRecorder {
return m.recorder
}
// AddOne mocks base method
func (m *MockMongoDB) AddOne(db *mongo.Collection, ctx context.Context, data interface{}) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddOne", db, ctx, data)
ret0, _ := ret[0].(error)
return ret0
}
// AddOne indicates an expected call of AddOne
func (mr *MockMongoDBMockRecorder) AddOne(db, ctx, data interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddOne", reflect.TypeOf((*MockMongoDB)(nil).AddOne), db, ctx, data)
}
// FindMany mocks base method
func (m *MockMongoDB) FindMany(db *mongo.Collection, ctx context.Context, filter bson.M) ([]map[string]interface{}, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FindMany", db, ctx, filter)
ret0, _ := ret[0].([]map[string]interface{})
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FindMany indicates an expected call of FindMany
func (mr *MockMongoDBMockRecorder) FindMany(db, ctx, filter interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindMany", reflect.TypeOf((*MockMongoDB)(nil).FindMany), db, ctx, filter)
}
测试
func TestGetPageAddFiles(t *testing.T) {
appId:="ecp"
flowKey:= "lcpzcs"
runId :="202103300020492"
var detail interface{}
ctrl := gomock.NewController(t)
defer ctrl.Finish() // 断言 DB.Get() 方法是否被调用
m := mock.NewMockMongoDB(ctrl)
filter := bson.M{"appId": appId, "flowKey": flowKey, "runId": runId}
var res []map[string]interface{}
var title = make(map[string]interface{})
res = append(res,title)
var content = make(map[string]interface{})
res = append(res,content)
m.EXPECT().FindMany(gomock.Any(),gomock.Any(),gomock.Eq(filter)).Return(res,errors.New("not exist"))
page, err := service.GetPageAddFiles(appId, flowKey, runId, detail,m)
if err!=nil {
t.Error("历史节点添加图片或者附件失败:",err)
} else {
t.Log("page:",util.GetJson(page))
}
}