最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go語(yǔ)言中GoMock安裝使用詳解

 更新時(shí)間:2022年11月24日 09:13:01   作者:洛天楓  
這篇文章主要為大家介紹了go語(yǔ)言中GoMock安裝使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

安裝

GoMock是一個(gè)Go框架。它與內(nèi)置的測(cè)試包整合得很好,并在單元測(cè)試時(shí)提供了靈活性。正如我們所知,對(duì)具有外部資源(數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)和文件)或依賴(lài)關(guān)系的代碼進(jìn)行單元測(cè)試總是很麻煩。

為了使用GoMock,我們需要安裝gomockgithub.com/golang/mock/gomockmockgen代碼生成工具github.com/golang/mock/mockgen。使用這個(gè)命令行:

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

GoMock的使用遵循四個(gè)基本步驟:

  • 使用mockgen為你想模擬的接口生成一個(gè)模擬對(duì)象。
  • 在測(cè)試部分,創(chuàng)建一個(gè)gomock.Controller的實(shí)例,并把它傳遞給你的mock對(duì)象的構(gòu)造函數(shù)以獲得一個(gè)mock對(duì)象。
  • 在mock上調(diào)用EXPECT()來(lái)設(shè)置期望值和返回值。
  • 在模擬控制器上調(diào)用Finish()來(lái)斷言模擬對(duì)象的期望。

開(kāi)始

讓我們創(chuàng)建一個(gè)這樣的文件夾(本代碼在 go1.16.15 版本下執(zhí)行)

gomock_test
├── doer
│ └── doer.go
├── mocks
│ └── mock_doer.go
└── user
  ├── user.go
  └── user_test.go

doer/doer.go

package doer
type Doer interface {
  DoSomething(int, string) error
  SaySomething(string) string
}

那么這里是我們?cè)谀MDoer接口時(shí)要測(cè)試的代碼。

user/user.go

package user
import "gomock_test/doer"
const (
	filtered   = "OK"
	unfiltered = "spam"
	Nice       = "nice"
	Bad        = "bad"
)
type User struct {
	// struct while mocking the doer interface
	Doer doer.Doer
}
// method Use using it
func (u *User) Use() error {
	return u.Doer.DoSomething(123, "Hello GoMock")
}
func (u *User) SaySomething(num int) string {
	if num == 3 {
		return u.Doer.SaySomething(unfiltered)
	}
	return u.Doer.SaySomething(filtered)
}
type Student struct{}
func (s *Student) DoSomething(_ int, _ string) error {
	panic("not implemented") // TODO: Implement
}
func (s *Student) SaySomething(kata string) string {
	if kata == filtered {
		return Nice
	}
	return Bad
}

我們將把Doer的模擬放在一個(gè)包mocks中。我們首先創(chuàng)建一個(gè)包含我們的模擬實(shí)現(xiàn)的目錄mocks,然后在doer包上運(yùn)行mockgen

mockgen -destination=../mocks/mock_doer.go -package=mocks gomock_test/doer Doer

NOTE: 在執(zhí)行這步的時(shí)候,會(huì)報(bào)錯(cuò):Failed to format generated source code: mocks/mock_doer.go:5:15: expected ';', found '.’ 這個(gè)時(shí)候,我們只需要將打印出來(lái)的代碼復(fù)制到我們對(duì)應(yīng)的文件中即可。

當(dāng)有大量的接口/包需要模擬時(shí),為每個(gè)包和接口運(yùn)行mockgen是一種烏托邦。為了緩解這個(gè)問(wèn)題,可以將mockgen命令與go:generate放在一起。

go:generate mockgen -destination=../mocks/mock_doer.go -package=mocks gomock_test/doer Doer

我們必須自己創(chuàng)建目錄模擬,因?yàn)镚oMock不會(huì)為我們這樣做,而是會(huì)以錯(cuò)誤退出。

  • destination=.../mocks/mock_doer.go : 把生成的mocks放在這個(gè)路徑下。
  • -package=mocks : 把生成的mocks放在這個(gè)包里
  • gomock_test/doer : 為這個(gè)包生成mocks。
  • Doer : 為這個(gè)接口生成mocks(必填),因?yàn)槲覀冃枰付膫€(gè)接口來(lái)生成mocks。(如果需要的話(huà),可以用逗號(hào)分隔的列表來(lái)指定多個(gè)接口。例如,Doer1, Doer2)

因?yàn)槲覀儗?duì)mockgen的調(diào)用在我們的項(xiàng)目中放置了一個(gè)文件mocks/mock_doer.go。這就是這樣一個(gè)生成的mock實(shí)現(xiàn)的樣子:

// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/timliudream/go-test/gomock_test/doer (interfaces: Doer)
// Package github.com/timliudream/go-test/gomock_test/mocks is a generated GoMock package.
package mocks
import (
	gomock "github.com/golang/mock/gomock"
	reflect "reflect"
)
// MockDoer is a mock of Doer interface.
type MockDoer struct {
	ctrl     *gomock.Controller
	recorder *MockDoerMockRecorder
}
// MockDoerMockRecorder is the mock recorder for MockDoer.
type MockDoerMockRecorder struct {
	mock *MockDoer
}
// NewMockDoer creates a new mock instance.
func NewMockDoer(ctrl *gomock.Controller) *MockDoer {
	mock := &MockDoer{ctrl: ctrl}
	mock.recorder = &MockDoerMockRecorder{mock}
	return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockDoer) EXPECT() *MockDoerMockRecorder {
	return m.recorder
}
// DoSomething mocks base method.
func (m *MockDoer) DoSomething(arg0 int, arg1 string) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DoSomething", arg0, arg1)
	ret0, _ := ret[0].(error)
	return ret0
}
// DoSomething indicates an expected call of DoSomething.
func (mr *MockDoerMockRecorder) DoSomething(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DoSomething", reflect.TypeOf((*MockDoer)(nil).DoSomething), arg0, arg1)
}
// SaySomething mocks base method.
func (m *MockDoer) SaySomething(arg0 string) string {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "SaySomething", arg0)
	ret0, _ := ret[0].(string)
	return ret0
}
// SaySomething indicates an expected call of SaySomething.
func (mr *MockDoerMockRecorder) SaySomething(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaySomething", reflect.TypeOf((*MockDoer)(nil).SaySomething), arg0)
}

接下來(lái),我們?cè)跍y(cè)試中定義一個(gè)模擬控制器。一個(gè)模擬控制器負(fù)責(zé)跟蹤和斷言其相關(guān)模擬對(duì)象的期望。我們可以通過(guò)傳遞一個(gè)*testing.T類(lèi)型的值給它的構(gòu)造函數(shù)來(lái)獲得一個(gè)模擬控制器,并使用它來(lái)構(gòu)造一個(gè)Doer接口的模擬對(duì)象。

//core of gomock
mockCtrl := gomock.NewController(t)
//used to trigger final assertions. if its ignored, mocking assertions will never fail
defer mockCtrl.Finish()
// create a new mock object, passing the controller instance as parameter
// for a newly created mock object it will accept any input and outpuite
// need to define its behavior with the method expect
mockDoer := mocks.NewMockDoer(mockCtrl)

使用參數(shù)匹配器

在GoMock中,一個(gè)參數(shù)可以被期望有一個(gè)固定的值,也可以被期望與一個(gè)謂詞(稱(chēng)為匹配器)相匹配。匹配器用于表示被模擬方法的預(yù)期參數(shù)范圍。下列匹配器在Gomock中被預(yù)先定義了:

  • gomock.Any() : 匹配任何值(任何類(lèi)型)。
  • gomock.Eq(x) : 使用反射來(lái)匹配與x深度相等的值。
  • gomock.Nil() : 匹配nil

user/user_test.go

package user
import (
	"fmt"
	"github.com/golang/mock/gomock"
	"gomock_test/mocks"
	"testing"
)
func TestUse(t *testing.T) {
	//core of gomock
	mockCtrl := gomock.NewController(t)
	//used to trigger final assertions. if its ignored, mocking assertions will never fail
	defer mockCtrl.Finish()
	// create a new mock object, passing the controller instance as parameter
	// for a newly created mock object it will accept any input and outpuite
	// need to define its behavior with the method expect
	mockDoer := mocks.NewMockDoer(mockCtrl)
	testUser := &User{Doer: mockDoer}
	//
	// Expect Do to be called once with 123 and "Hello GoMock" as parameters, and return nil from the mocked call.
	mockDoer.EXPECT().DoSomething(123, "Hello GoMock").Return(nil).Times(1)
	fmt.Println(testUser.Use())
	fmt.Println()
}
func TestUser_SaySomething(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()
	mockDoer := mocks.NewMockDoer(mockCtrl)
	user := User{
		Doer: mockDoer,
	}
	type args struct {
		num int
	}
	tests := []struct {
		name    string
		args    args
		want    string
		expect  func()
		wantErr bool
	}{
		{
			name: "Positive test case 1",
			expect: func() {
				mockDoer.EXPECT().SaySomething("spam").Return("bad")
			},
			args:    args{num: 3},
			wantErr: false,
			want:    "bad",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			tt.expect()
			if got := user.SaySomething(tt.args.num); (got != tt.want) != tt.wantErr {
				fmt.Println("gott :", got)
				t.Errorf("User.SaySomething() = %v, want %v", got, tt.want)
			}
		})
	}
}

而單元測(cè)試的結(jié)果將是這樣的:

=== RUN   TestUser_SaySomething
=== RUN   TestUser_SaySomething/Positive_test_case_1
--- PASS: TestUser_SaySomething (0.00s)
    --- PASS: TestUser_SaySomething/Positive_test_case_1 (0.00s)
PASS
ok      github.com/tokopedia/go_learning/udemy/pzn/gomock_test/user     1.100s

經(jīng)驗(yàn)之談

可以在不調(diào)用外部依賴(lài)的情況下進(jìn)行單元測(cè)試。使用mocking框架可以在很多方面幫助我們,建立干凈和輕量級(jí)的單元測(cè)試。與接口和依賴(lài)注入相結(jié)合。

以上就是go語(yǔ)言中GoMock安裝使用詳解的詳細(xì)內(nèi)容,更多關(guān)于go語(yǔ)言GoMock安裝的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • golang分層測(cè)試之http接口測(cè)試入門(mén)教程

    golang分層測(cè)試之http接口測(cè)試入門(mén)教程

    這篇文章主要介紹了golang分層測(cè)試之http接口測(cè)試入門(mén)教程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • 詳解Golang實(shí)現(xiàn)http重定向https的方式

    詳解Golang實(shí)現(xiàn)http重定向https的方式

    這篇文章主要介紹了詳解Golang實(shí)現(xiàn)http重定向https的方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Golang分布式注冊(cè)中心實(shí)現(xiàn)流程講解

    Golang分布式注冊(cè)中心實(shí)現(xiàn)流程講解

    這篇文章主要介紹了Golang分布式注冊(cè)中心實(shí)現(xiàn)流程,注冊(cè)中心可以用于服務(wù)發(fā)現(xiàn),服務(wù)注冊(cè),配置管理等方面,在分布式系統(tǒng)中,服務(wù)的發(fā)現(xiàn)和注冊(cè)是非常重要的組成部分,需要的朋友可以參考下
    2023-05-05
  • 入門(mén)學(xué)習(xí)Go的基本語(yǔ)法

    入門(mén)學(xué)習(xí)Go的基本語(yǔ)法

    這篇文章主要介紹了Go語(yǔ)法的基本概念,本文講解了Golang的基本知識(shí)、基礎(chǔ)語(yǔ)法、相關(guān)術(shù)語(yǔ)等,需要的朋友可以參考下,希望能幫助到你
    2021-07-07
  • Golang實(shí)現(xiàn)讀取excel文件并轉(zhuǎn)換為JSON格式

    Golang實(shí)現(xiàn)讀取excel文件并轉(zhuǎn)換為JSON格式

    本文介紹了如何使用Golang讀取Excel文件并將其轉(zhuǎn)換為JSON格式,通過(guò)安裝excelize依賴(lài)和創(chuàng)建readExcelToJSON方法,可以實(shí)現(xiàn)這一功能,如果需要轉(zhuǎn)換數(shù)據(jù)類(lèi)型,可以修改相應(yīng)的代碼,需要的朋友可以參考下
    2025-03-03
  • golang協(xié)程關(guān)閉踩坑實(shí)戰(zhàn)記錄

    golang協(xié)程關(guān)閉踩坑實(shí)戰(zhàn)記錄

    協(xié)程(coroutine)是Go語(yǔ)言中的輕量級(jí)線(xiàn)程實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于golang協(xié)程關(guān)閉踩坑的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • go學(xué)習(xí)筆記讀取consul配置文件詳解

    go學(xué)習(xí)筆記讀取consul配置文件詳解

    這篇文章主要為大家介紹了go學(xué)習(xí)筆記讀取consul配置文件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • golang判斷結(jié)構(gòu)體為空的問(wèn)題

    golang判斷結(jié)構(gòu)體為空的問(wèn)題

    這篇文章主要介紹了golang判斷結(jié)構(gòu)體為空的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 如何使用Goland IDE go mod 方式構(gòu)建項(xiàng)目

    如何使用Goland IDE go mod 方式構(gòu)建項(xiàng)目

    這篇文章主要介紹了如何使用Goland IDE go mod 方式構(gòu)建項(xiàng)目,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 詳解Go語(yǔ)言變量作用域

    詳解Go語(yǔ)言變量作用域

    這篇文章主要介紹了Go 語(yǔ)言變量作用域的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用go語(yǔ)言,感興趣的朋友可以了解下
    2021-03-03

最新評(píng)論

东莞市| 海南省| 车险| 筠连县| 深州市| 东乡| 石台县| 怀安县| 虞城县| 乃东县| 江华| 尤溪县| 宁陵县| 霍州市| 平谷区| 平武县| 正镶白旗| 崇礼县| 天柱县| 南康市| 禄丰县| 蒙城县| 星座| 安泽县| 双牌县| 定襄县| 宣恩县| 普兰店市| 安宁市| 信宜市| 威宁| 工布江达县| 南郑县| 开平市| 宝山区| 台安县| 天祝| 鄢陵县| 开化县| 安仁县| 集贤县|