<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在 Golang 語言中,寫單元測試的時候,不可避免的會涉及到對其他函數及方法的 Mock,即在假設其他函數及方法響應預期結果的同時,校驗被測函數的響應是否符合預期。
其中,在 Mock 其他函數及方法的時候,我們常用到的一個測試類庫是「gomonkey」。特別地,對於方法和函數的 Mock,略有差異,在這裡我們就分別給出函數和方法 Mock 範例,方便大家參考。
在 Golang 語言中,函數是沒有接受者的方法,其形式為
func function_name([parameter list]) [return_types] { 函數體 }
對於函數的 Mock 相對來說比較簡單,假設我們對 A 函數進行單元測試,且 A 函數裡面又呼叫了 B 函數,例如
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 函數的每一行程式碼都覆蓋到,則其單元測試可以寫為:
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: "正常響應", 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, }, } // 執行測試用例 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 不符合預期") } }) } }
其中,ApplyFunc
函數是用來 Mock 函數的,其第一個引數為需要 Mock 的函數名稱(不需要寫參數列),第二個引數為需要 Mock 的函數結果;特別地,在Setup
裡面,我們要記得顯式呼叫Cleanup
對patches
進行Reset
操作,防止該 Mock 影響其他測試用例。
在 Golang 語言中,方法是含有接受者的函數,其形式為
func (variable_name variable_data_type) function_name([parameter list]) [return_type]{ 函數體 }
對於方法的 Mock 相對來說複雜一下,假設我們對 A 函數進行單元測試,且 A 函數裡面又呼叫了結構 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 函數的每一行程式碼都覆蓋到,則其單元測試可以寫為:
func TestA(t *testing.T) { // 初始化C結構 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: "正常響應", 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, }, } // 執行測試用例 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 不符合預期") } }) } }
其中,ApplyMethod
函數是用來 Mock 方法的,其第一個引數為需要 Mock 的方法的接受者型別,第二個引數為需要 Mock 的方法名稱(字串型別),第三個引數為需要 Mock 的方法的定義及 Mock 結果;特別地,第一個引數和第三個引數需要我們注意:
reflect.TypeOf
獲取接受者的型別,初始化的接受者必須是真正的型別,如結構 C 組合了結構 D,而B
方法是通過組合 D 得到的,則初始化的時候需要定義結構 D,而不是結構 C,否則會報空指標異常;B
方法的宣告是func(ctx context.Context, str string)
,但是在使用ApplyMethod
的時候,需要將B
方法的宣告修改為func(c *test_package_name.C, ctx context.Context, str string)
,即需要將方法的接受者置為方法的第一個引數。還有就是,大家在使用gomonkey
的時候,有可能遇到許可權校驗的問題以及非 Debug 模式執行失敗的問題,可以參考:
golang使用gomonkey和monkey來mock方法或者函數時報panic: permission denied
使用 gomonkey 遇到非 debug 模式執行失敗的問題及解決方法
到這裡,本文就要結束了,希望對大家有所幫助。
到此這篇關於使用 gomonkey Mock 函數及方法的文章就介紹到這了,更多相關gomonkey Mock 函數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45