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

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

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

前言

在 Golang 語言中,寫單元測(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è)試類庫是「gomonkey」。特別地,對(duì)于方法和函數(shù)的 Mock,略有差異,在這里我們就分別給出函數(shù)和方法 Mock 示例,方便大家參考。

函數(shù)

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

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

對(duì)于函數(shù)的 Mock 相對(duì)來說比較簡單,假設(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è)試可以寫為:

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

方法

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

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

對(duì)于方法的 Mock 相對(duì)來說復(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è)試可以寫為:

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ù)是用來 Mock 方法的,其第一個(gè)參數(shù)為需要 Mock 的方法的接受者類型,第二個(gè)參數(shù)為需要 Mock 的方法名稱(字符串類型),第三個(gè)參數(shù)為需要 Mock 的方法的定義及 Mock 結(jié)果;特別地,第一個(gè)參數(shù)和第三個(gè)參數(shù)需要我們注意:

  • 第一個(gè)參數(shù),需要使用reflect.TypeOf獲取接受者的類型,初始化的接受者必須是真正的類型,如結(jié)構(gòu) C 組合了結(jié)構(gòu) D,而B方法是通過組合 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)的問題以及非 Debug 模式運(yùn)行失敗的問題,可以參考:

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

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

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

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

相關(guān)文章

  • Go語言開源庫實(shí)現(xiàn)Onvif協(xié)議客戶端設(shè)備搜索

    Go語言開源庫實(shí)現(xiàn)Onvif協(xié)議客戶端設(shè)備搜索

    這篇文章主要為大家介紹了Go語言O(shè)nvif協(xié)議客戶端設(shè)備搜索示例實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Go語言中循環(huán)Loop的用法介紹

    Go語言中循環(huán)Loop的用法介紹

    這篇文章介紹了Go語言中循環(huán)Loop的用法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 詳解Go語言中init的使用與常見應(yīng)用場(chǎng)景

    詳解Go語言中init的使用與常見應(yīng)用場(chǎng)景

    Go?中有一個(gè)特別的?init()?函數(shù),它主要用于包的初始化,這篇文章將以此為主題介紹?Go?中?init()?函數(shù)的使用和常見使用場(chǎng)景,希望對(duì)大家有所幫助
    2024-02-02
  • Go語言同步與異步執(zhí)行多個(gè)任務(wù)封裝詳解(Runner和RunnerAsync)

    Go語言同步與異步執(zhí)行多個(gè)任務(wù)封裝詳解(Runner和RunnerAsync)

    這篇文章主要給大家介紹了關(guān)于Go語言同步與異步執(zhí)行多個(gè)任務(wù)封裝(Runner和RunnerAsync)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • 一文帶你掌握Go語言中文件的寫入操作

    一文帶你掌握Go語言中文件的寫入操作

    這篇文章主要和大家分享一下Go語言中文件的寫入操作,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語言有一定的幫助,需要的小伙伴可以參考一下
    2022-12-12
  • Golang sync包中errgroup的使用詳解

    Golang sync包中errgroup的使用詳解

    Go 語言為我們提供了豐富的并發(fā)原語,且大多數(shù)都位于 sync 包下,今天我們來探討一下該庫下的原語之一:errgroup,感興趣的小伙伴可以了解一下
    2023-05-05
  • golang?字符串拼接方法對(duì)比分析

    golang?字符串拼接方法對(duì)比分析

    這篇文章主要為大家介紹了golang?字符串拼接方法對(duì)比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Go處理包含多種引號(hào)的字符串的幾種方法

    Go處理包含多種引號(hào)的字符串的幾種方法

    在Go中,有幾種方式可以處理包含多種引號(hào)的字符串,以確保代碼的可讀性和正確性,本文將給大家詳細(xì)介紹了這幾種處理方式,并通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • go語言中使用ent做關(guān)聯(lián)查詢的示例詳解

    go語言中使用ent做關(guān)聯(lián)查詢的示例詳解

    go語言的ent框架是facebook開源的ORM框架,是go語言開發(fā)中的常用框架,而關(guān)聯(lián)查詢又是日常開發(fā)中的常見數(shù)據(jù)庫操作,故文本給出一個(gè)使用ent做關(guān)聯(lián)查詢的使用示例,需要的朋友可以參考下
    2024-02-02
  • 詳細(xì)介紹Go語言之?dāng)?shù)組與切片

    詳細(xì)介紹Go語言之?dāng)?shù)組與切片

    這篇文章介紹Go語言之?dāng)?shù)組與切片,數(shù)組是具有相同唯一類型的一組已編號(hào)且長度固定的數(shù)據(jù)項(xiàng)序列,這種類型可是任意的原始類型如整形、字符串或自定義類型。切片是數(shù)組的一個(gè)引用,因此切片是引用類型,在進(jìn)行傳遞時(shí),遵守引用傳遞的機(jī)制,下面我們就來詳細(xì)了解一下該內(nèi)容
    2021-10-10

最新評(píng)論

顺义区| 嘉荫县| 子洲县| 久治县| 棋牌| 绍兴县| 徐闻县| 大丰市| 义乌市| 荃湾区| 南充市| 正蓝旗| 浦北县| 沛县| 喀喇| 康马县| 苏尼特右旗| 新竹县| 吴堡县| 库伦旗| 合川市| 佛山市| 柯坪县| 阜南县| 监利县| 张北县| 扶余县| 揭阳市| 称多县| 呼伦贝尔市| 呼图壁县| 简阳市| 孙吴县| 延吉市| 阿拉善右旗| 石林| 新昌县| 扎兰屯市| 黑河市| 武安市| 镇安县|