go-单元测试和 mock测试

学习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))
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单元测试是一种软件测试方法,用于测试应用程序的各个部分是否按照预期进行工作。在 Golang 中,我们可以使用 Mock 对象来编写单元测试Mock 对象可以模拟应用程序的行为,以便进行测试。 以下是使用 Golang 编写 Mock 单元测试的步骤: 1. 安装 Mock 库 在 Golang 中,我们可以使用各种 Mock 库,例如 GoMockMockery 等。在本例中,我们将使用 GoMock 库。请使用以下命令安装 GoMock: ``` go get github.com/golang/mock/gomock ``` 2. 创建 Mock 对象 在 Golang 中,我们可以使用 Mock 对象来模拟应用程序的行为。我们可以使用 GoMock 库来创建 Mock 对象。以下是一个示例: ``` // mock_test.go package main import ( "testing" "github.com/golang/mock/gomock" ) type MockDatabase struct { mock.Mock } func (m *MockDatabase) GetUser(id int) (string, error) { args := m.Called(id) return args.String(0), args.Error(1) } ``` 在上面的示例中,我们创建了一个名为 `MockDatabase` 的结构体,该结构体包含一个 `mock.Mock` 字段。我们还定义了一个 `GetUser` 方法,该方法接受一个 `id` 参数,并返回一个字符串和一个错误。在该方法中,我们使用 `m.Called` 方法来模拟一个函数调用,并返回模拟的结果。 3. 编写测试用例 编写测试用例时,我们可以使用 `gomock.NewController` 方法来创建一个 Mock 控制器,并使用 `controller.Finish` 方法来释放资源。以下是一个示例: ``` // main_test.go package main import ( "testing" "github.com/golang/mock/gomock" ) func TestGetUser(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockDatabase := NewMockDatabase(ctrl) mockDatabase.EXPECT().GetUser(1).Return("Alice", nil) app := App{ Database: mockDatabase, } user, err := app.GetUser(1) if err != nil { t.Errorf("Unexpected error: %v", err) } if user != "Alice" { t.Errorf("Expected user to be Alice, but got %v", user) } } ``` 在上面的示例中,我们创建了一个名为 `TestGetUser` 的测试用例。在该测试用例中,我们使用 `gomock.NewController` 方法创建了一个 Mock 控制器,并使用 `ctrl.Finish` 方法释放资源。我们还创建了一个名为 `mockDatabase` 的 Mock 对象,并使用 `mockDatabase.EXPECT().GetUser(1).Return("Alice", nil)` 方法来模拟 `GetUser` 方法的行为。最后,我们使用模拟的 `Database` 对象创建了一个 `App` 对象,并调用 `GetUser` 方法进行测试。 总结 在 Golang 中,我们可以使用 Mock 对象来编写单元测试。使用 Mock 对象可以模拟应用程序的行为,以便进行测试。在本文中,我们介绍了使用 GoMock 库编写 Mock 单元测试的步骤,并提供了示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值