網站首頁 編程語言 正文
前言
在 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 模式執行失敗的問題及解決方法
到這里,本文就要結束了,希望對大家有所幫助。
原文鏈接:https://blog.csdn.net/qq_35246620/article/details/125096233
相關推薦
- 2022-06-20 樹莓派ASP.NET環境配置過程詳解_實用技巧
- 2022-06-17 Ruby序列化和持久化存儲(Marshal、Pstore)操作方法詳解_Golang
- 2022-06-16 gin框架中使用JWT的定義需求及解析_Golang
- 2022-08-21 Android實現動態曲線繪制_Android
- 2022-11-28 詳解如何使用C++寫一個線程安全的單例模式_C 語言
- 2022-06-17 C語言詳解函數與指針的使用_C 語言
- 2022-08-19 android九宮格鎖屏控件使用詳解_Android
- 2022-04-21 Python的基礎語法和輸入輸出函數你都了解嗎_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支