欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用?gomonkey?Mock?函數(shù)及方法示例詳解

 更新時(shí)間:2022年06月02日 14:20:47   作者:CG國(guó)斌  
在 Golang 語(yǔ)言中,寫(xiě)單元測(cè)試的時(shí)候,不可避免的會(huì)涉及到對(duì)其他函數(shù)及方法的 Mock,即在假設(shè)其他函數(shù)及方法響應(yīng)預(yù)期結(jié)果的同時(shí),校驗(yàn)被測(cè)函數(shù)的響應(yīng)是否符合預(yù)期,這篇文章主要介紹了使用?gomonkey?Mock?函數(shù)及方法,需要的朋友可以參考下

前言

在 Golang 語(yǔ)言中,寫(xiě)單元測(cè)試的時(shí)候,不可避免的會(huì)涉及到對(duì)其他函數(shù)及方法的 Mock,即在假設(shè)其他函數(shù)及方法響應(yīng)預(yù)期結(jié)果的同時(shí),校驗(yàn)被測(cè)函數(shù)的響應(yīng)是否符合預(yù)期。

其中,在 Mock 其他函數(shù)及方法的時(shí)候,我們常用到的一個(gè)測(cè)試類(lèi)庫(kù)是「gomonkey」。特別地,對(duì)于方法和函數(shù)的 Mock,略有差異,在這里我們就分別給出函數(shù)和方法 Mock 示例,方便大家參考。

函數(shù)

在 Golang 語(yǔ)言中,函數(shù)是沒(méi)有接受者的方法,其形式為

func function_name([parameter list]) [return_types] {
   函數(shù)體
}

對(duì)于函數(shù)的 Mock 相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,假設(shè)我們對(duì) A 函數(shù)進(jìn)行單元測(cè)試,且 A 函數(shù)里面又調(diào)用了 B 函數(shù),例如

func A(ctx context.Context, str string) error {
   if len(str) == 0 {
	  return errors.New("str is empty")
   }
   return test_package_name.B(ctx, str)
}

為了將 A 函數(shù)的每一行代碼都覆蓋到,則其單元測(cè)試可以寫(xiě)為:

func TestA(t *testing.T) {
	type args struct {
		ctx    context.Context
		str    string
	}
	tests := []struct {
		name    string
		args    args
		Setup   func(t *testing.T)
		wantErr error
	}{
		{
			name: "len(str) == 0",
			wantErr: errors.New("str is empty")
		},
		{
			name: "正常響應(yīng)",
			Setup: func(t *testing.T) {
				patches := gomonkey.ApplyFunc(test_package_name.B, func(_ context.Context, _ string) error {
					return nil
				})
				t.Cleanup(func() {
					patches.Reset()
				})
			},
			args: args{
				ctx:     context.Background(),
				str:     "test",
			},
			wantErr: nil,
		},
	}

	// 執(zhí)行測(cè)試用例
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.Setup != nil {
				tt.Setup(t)
			}
			err := A(tt.args.ctx, tt.args.str)
			if err != nil {
				assert.EqualError(t, err, tt.wantErr.Error(), "error 不符合預(yù)期")
			}
		})
	}
}

其中,ApplyFunc函數(shù)是用來(lái) Mock 函數(shù)的,其第一個(gè)參數(shù)為需要 Mock 的函數(shù)名稱(chēng)(不需要寫(xiě)參數(shù)列表),第二個(gè)參數(shù)為需要 Mock 的函數(shù)結(jié)果;特別地,在Setup里面,我們要記得顯式調(diào)用Cleanup對(duì)patches進(jìn)行Reset操作,防止該 Mock 影響其他測(cè)試用例。

方法

在 Golang 語(yǔ)言中,方法是含有接受者的函數(shù),其形式為

func (variable_name variable_data_type) function_name([parameter list]) [return_type]{
   函數(shù)體
}

對(duì)于方法的 Mock 相對(duì)來(lái)說(shuō)復(fù)雜一下,假設(shè)我們對(duì) A 函數(shù)進(jìn)行單元測(cè)試,且 A 函數(shù)里面又調(diào)用了結(jié)構(gòu) C 的 B 方法,例如

func A(ctx context.Context, str string) error {
   if len(str) == 0 {
	  return errors.New("str is empty")
   }
   c := &test_package_name.C{}
   return c.B(ctx, str)
}

為了將 A 函數(shù)的每一行代碼都覆蓋到,則其單元測(cè)試可以寫(xiě)為:

func TestA(t *testing.T) {
	// 初始化C結(jié)構(gòu)
	var c *test_package_name.C
	
	type args struct {
		ctx    context.Context
		str    string
	}
	tests := []struct {
		name    string
		args    args
		Setup   func(t *testing.T)
		wantErr error
	}{
		{
			name: "len(str) == 0",
			wantErr: errors.New("str is empty")
		},
		{
			name: "正常響應(yīng)",
			Setup: func(t *testing.T) {
				patches := gomonkey.ApplyMethod(reflect.TypeOf(c), "B", func(_ *test_package_name.C, _ context.Context, _ string) error {
					return nil
				})
				t.Cleanup(func() {
					patches.Reset()
				})
			},
			args: args{
				ctx:     context.Background(),
				str:     "test",
			},
			wantErr: nil,
		},
	}

	// 執(zhí)行測(cè)試用例
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.Setup != nil {
				tt.Setup(t)
			}
			err := A(tt.args.ctx, tt.args.str)
			if err != nil {
				assert.EqualError(t, err, tt.wantErr.Error(), "error 不符合預(yù)期")
			}
		})
	}
}

其中,ApplyMethod函數(shù)是用來(lái) Mock 方法的,其第一個(gè)參數(shù)為需要 Mock 的方法的接受者類(lèi)型,第二個(gè)參數(shù)為需要 Mock 的方法名稱(chēng)(字符串類(lèi)型),第三個(gè)參數(shù)為需要 Mock 的方法的定義及 Mock 結(jié)果;特別地,第一個(gè)參數(shù)和第三個(gè)參數(shù)需要我們注意:

  • 第一個(gè)參數(shù),需要使用reflect.TypeOf獲取接受者的類(lèi)型,初始化的接受者必須是真正的類(lèi)型,如結(jié)構(gòu) C 組合了結(jié)構(gòu) D,而B方法是通過(guò)組合 D 得到的,則初始化的時(shí)候需要定義結(jié)構(gòu) D,而不是結(jié)構(gòu) C,否則會(huì)報(bào)空指針異常;
  • 第三個(gè)參數(shù),雖然B方法的聲明是func(ctx context.Context, str string),但是在使用ApplyMethod的時(shí)候,需要將B方法的聲明修改為func(c *test_package_name.C, ctx context.Context, str string),即需要將方法的接受者置為方法的第一個(gè)參數(shù)。

參考

還有就是,大家在使用gomonkey的時(shí)候,有可能遇到權(quán)限校驗(yàn)的問(wèn)題以及非 Debug 模式運(yùn)行失敗的問(wèn)題,可以參考:

golang使用gomonkey和monkey來(lái)mock方法或者函數(shù)時(shí)報(bào)panic: permission denied

使用 gomonkey 遇到非 debug 模式執(zhí)行失敗的問(wèn)題及解決方法

到這里,本文就要結(jié)束了,希望對(duì)大家有所幫助。

到此這篇關(guān)于使用 gomonkey Mock 函數(shù)及方法的文章就介紹到這了,更多相關(guān)gomonkey Mock 函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang基礎(chǔ)學(xué)習(xí)之map的示例詳解

    Golang基礎(chǔ)學(xué)習(xí)之map的示例詳解

    哈希表是常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),有的語(yǔ)言會(huì)將哈希稱(chēng)作字典或者映射,在Go中,哈希就是常見(jiàn)的數(shù)據(jù)類(lèi)型map,本文就來(lái)聊聊Golang中map的相關(guān)知識(shí)吧
    2023-03-03
  • 淺析Go匯編語(yǔ)法和MatrixOne使用介紹

    淺析Go匯編語(yǔ)法和MatrixOne使用介紹

    MatrixOne由Go語(yǔ)言所開(kāi)發(fā)是一個(gè)新一代超融合異構(gòu)數(shù)據(jù)庫(kù),致力于打造單一架構(gòu)處理TP、AP、流計(jì)算等多種負(fù)載的極簡(jiǎn)大數(shù)據(jù)引擎,今天通過(guò)本文給大家介紹Go匯編語(yǔ)法和MatrixOne使用,感興趣的朋友一起看看吧
    2022-04-04
  • Go語(yǔ)言應(yīng)用閉包之返回函數(shù)

    Go語(yǔ)言應(yīng)用閉包之返回函數(shù)

    這篇文章主要介紹了Go語(yǔ)言應(yīng)用閉包之返回函數(shù),對(duì)于非常底層的純 Go 語(yǔ)言代碼或者包而言,在各個(gè)操作系統(tǒng)平臺(tái)上的可移植性是非常強(qiáng)的,只需要將源碼拷貝到相應(yīng)平臺(tái)上進(jìn)行編譯即可,或者可以使用交叉編譯來(lái)構(gòu)建目標(biāo)平臺(tái)的應(yīng)用程序,需要的朋友可以參考下
    2023-07-07
  • Golang實(shí)現(xiàn)簡(jiǎn)易的命令行功能

    Golang實(shí)現(xiàn)簡(jiǎn)易的命令行功能

    這篇文章主要為大家詳細(xì)介紹了如何通過(guò)Golang實(shí)現(xiàn)一個(gè)簡(jiǎn)易的命令行功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-02-02
  • 深入了解Golang的指針用法

    深入了解Golang的指針用法

    與C語(yǔ)言一樣,Go語(yǔ)言中同樣有指針,通過(guò)指針,我們可以只傳遞變量的內(nèi)存地址,而不是傳遞整個(gè)變量,這在一定程度上可以節(jié)省內(nèi)存的占用。本文將通過(guò)示例詳細(xì)講講Golang的指針用法,需要的可以參考一下
    2022-07-07
  • golang 微服務(wù)之gRPC與Protobuf的使用

    golang 微服務(wù)之gRPC與Protobuf的使用

    這篇文章主要介紹了golang 微服務(wù)之gRPC與Protobuf的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Go?常見(jiàn)設(shè)計(jì)模式之單例模式詳解

    Go?常見(jiàn)設(shè)計(jì)模式之單例模式詳解

    單例模式是設(shè)計(jì)模式中最簡(jiǎn)單的一種模式,單例模式能夠確保無(wú)論對(duì)象被實(shí)例化多少次,全局都只有一個(gè)實(shí)例存在,在Go?語(yǔ)言有多種方式可以實(shí)現(xiàn)單例模式,所以我們今天就來(lái)一起學(xué)習(xí)下吧
    2023-07-07
  • golang中的時(shí)間格式化

    golang中的時(shí)間格式化

    這篇文章主要介紹了golang中的時(shí)間格式化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • golang語(yǔ)法使用的注意事項(xiàng)

    golang語(yǔ)法使用的注意事項(xiàng)

    這篇文章主要給大家介紹了關(guān)于golang語(yǔ)法使用的一些注意事項(xiàng),Golang是一種靜態(tài)類(lèi)型的編程語(yǔ)言,它支持基本的數(shù)據(jù)類(lèi)型,包括整型、浮點(diǎn)型、布爾型、字符串型,需要的朋友可以參考下
    2023-07-07
  • 深入剖析Go語(yǔ)言中的Select語(yǔ)句

    深入剖析Go語(yǔ)言中的Select語(yǔ)句

    select是Go中的一個(gè)控制結(jié)構(gòu),類(lèi)似于switch語(yǔ)句,本文主要介紹了深入剖析Go語(yǔ)言中的Select語(yǔ)句,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12

最新評(píng)論