mock工具GoMock使用

GoMock

gomock 是官方提供的 mock 框架,同时还提供了 mockgen 工具用来辅助生成测试代码。

go get -u github.com/golang/mock/gomock go get -u github.com/golang/mock/mockgen

简单的使用方法:

// db.go
 type DB interface {
   Get(key string) (int, error)
 }
 
 func GetFromDB(db DB, key string) int {
   if value, err := db.Get(key); err == nil {
     return value
   }
 
   return -1
 }
 复制代码

有一个DB接口,使用mockgen产生一个mock对象

mockgen -source=db.go -destination=db_mock.go -package=main

下面是自动生成的代码

// Code generated by MockGen. DO NOT EDIT.
 // Source: db.go
 
 // Package mian is a generated GoMock package.
 package mian
 
 import (
    reflect "reflect"
 
    gomock "github.com/golang/mock/gomock"
 )
 
 // MockDB is a mock of DB interface.
 type MockDB struct {
    ctrl     *gomock.Controller
    recorder *MockDBMockRecorder
 }
 
 // MockDBMockRecorder is the mock recorder for MockDB.
 type MockDBMockRecorder struct {
    mock *MockDB
 }
 
 // NewMockDB creates a new mock instance.
 func NewMockDB(ctrl *gomock.Controller) *MockDB {
    mock := &MockDB{ctrl: ctrl}
    mock.recorder = &MockDBMockRecorder{mock}
    return mock
 }
 
 // EXPECT returns an object that allows the caller to indicate expected use.
 func (m *MockDB) EXPECT() *MockDBMockRecorder {
    return m.recorder
 }
 
 // Get mocks base method.
 func (m *MockDB) Get(key string) (int, error) {
    m.ctrl.T.Helper()
    ret := m.ctrl.Call(m, "Get", key)
    ret0, _ := ret[0].(int)
    ret1, _ := ret[1].(error)
    return ret0, ret1
 }
 
 // Get indicates an expected call of Get.
 func (mr *MockDBMockRecorder) Get(key interface{}) *gomock.Call {
    mr.mock.ctrl.T.Helper()
    return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDB)(nil).Get), key)
 }
 复制代码

在测试的使用mock对象

func TestGetFromDB(t *testing.T) {
   ctrl := gomock.NewController(t)
   defer ctrl.Finish() // 断言 DB.Get() 方法是否被调用
 
   m := NewMockDB(ctrl)
   m.EXPECT().Get(gomock.Eq("Tom")).Return(100, errors.New("not exist")) //设置期望返回结果,可以设置可调用次数times/AnyTimes
 
   if v := GetFromDB(m, "Tom"); v != -1 {
     t.Fatal("expected -1, but got", v)
   }
 }
 复制代码

goMock支持对特定输入打桩和对任意输入打桩(gomock.any()),可根据具体情况使用;

实际项目中,可以用gomock来mock dao层和rpc层代码,隔离外部依赖

你可能感兴趣的:(java,开发语言)