<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## <span style="font-size:15px">**一、說明**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GoMock是由Golang官方開發維護的測試框架,實現了較為完整的基于interface的Mock功能,能夠與Golang內置的testing包良好集成,也能用于其它的測試環境中。GoMock測試框架包含了GoMock包和mockgen工具兩部分,其中GoMock包完成對樁對象生命周期的管理,mockgen工具用來生成interface對應的Mock類源文件。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GoMock官網:`https://github.com/golang/mock` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GoMock文檔:`go doc github.com/golang/mock/gomock` ## <span style="font-size:15px">**二、安裝**</span> ``` go get -u github.com/golang/mock/gomock go get -u github.com/golang/mock/mockgen ``` ## <span style="font-size:15px">**三、mockgen工具**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mockgen有兩種操作模式:源文件模式和反射模式。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;源文件模式通過一個包含interface定義的源文件生成mock類文件,通過-source標識開啟,-imports和-aux_files標識在源文件模式下是有用的。mockgen源文件模式的命令格式如下: ``` mockgen -source=xxxx.go [other options] ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;反射模式通過構建一個程序用反射理解接口生成一個mock類文件,通過兩個非標志參數開啟:導入路徑和用逗號分隔的符號列表(多個interface)。mockgen反射模式的命令格式如下: ``` // 第一個參數 packagepath 是基于GOPATH的相對路徑 // 第二個參數可以為多個interface,并且interface之間只能用逗號分隔,不能有空格。 mockgen packagepath Interface1,Interface2... ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mockgen工作模式適用場景如下: * 對于簡單場景,只需使用-source選項。 * 對于復雜場景,如一個源文件定義了多個interface而只想對部分interface進行mock,或者interface存在嵌套,則需要使用反射模式。 ## <span style="font-size:15px">**四、GoMock常用方法**</span> ### <span style="font-size:15px">**1、gomock.Call**</span> ``` type Call struct { t TestHelper // for triggering test failures on invalid call setup receiver interface{} // the receiver of the method call method string // the name of the method methodType reflect.Type // the type of the method args []Matcher // the args origin string // file and line number of call setup preReqs []*Call // prerequisite calls // Expectations minCalls, maxCalls int numCalls int // actual number made // actions are called when this Call is called. Each action gets the args and // can set the return values by returning a non-nil slice. Actions run in the // order they are created. actions []func([]interface{}) []interface{} } ``` | 函數 | 說明 | | --- | --- | | func (c \*Call) After(preReq \*Call) \*Call | After聲明調用在preReq完成后執行 | | func (c *Call) AnyTimes() *Call | 允許調用0次或多次 | | func (c *Call) MinTimes(n int) *Call | 設置最小的調用次數為n次 | | func (c *Call) MaxTimes(n int) *Call | 設置最大的調用次數為n次 | | func (c *Call) DoAndReturn(f interface{}) *Call | 聲明在匹配時要運行的操作,并設置mock函數所需要的返回值 | | func (c *Call) Do(f interface{}) *Call | 聲明在匹配時要運行的操作 | | func (c *Call) Return(rets ...interface{}) *Call | 設置mock函數調用要返回值 | | func (c *Call) Times(n int) *Call | 設置調用的次數為n次 | | func (c *Call) SetArg(n int, value interface{}) *Call | 設置參數 | ### <span style="font-size:15px">**2、gomock.Controller**</span> | 函數 | 說明 | | --- | --- | | func NewController(t TestReporter) \*Controller | 返回一個實例化控制器 | | func (ctrl \*Controller) Call(receiver interface{}, method string, args ...interface{}) \[\]interface{} | 模擬 Mock 對象的方法調用,并返回預先設定的結果 | | func (ctrl *Controller) Finish() | 檢查是否調用了所有預期調用的方法 | | func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call| 用于記錄 Mock 對象的方法調用。當你希望在測試中驗證某個方法是否被調用,你可以使用 RecordCall 函數來記錄這個調用,以便后續進行斷言 | | func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call | 與 RecordCall 類似,不同之處在于它還需要傳入方法的類型信息。這個函數通常用于記錄接口類型的方法調用,以便在后續的斷言中進行類型匹配 | ## <span style="font-size:15px">**五、使用 mock 對象進行打樁測試**</span> ### <span style="font-size:15px">**1、導入 mock 相關的包**</span> ``` import?( ????.?"github.com/golang/mock/gomock" ) ``` ### <span style="font-size:15px">**2、生成 mock 類文件**</span> calculator.go文件內容如下 ``` package util type Calculator interface { Add(a, b int) int Subtract(a, b int) int } type MyCalculator struct{} func (c *MyCalculator) Add(a, b int) int { return a + b } func (c *MyCalculator) Subtract(a, b int) int { return a - b } ``` 執行mockgen命令生成mock類文件 ``` mockgen -source=calculator.go -destination=calculator_mock.go -package=util ``` ``` // Code generated by MockGen. DO NOT EDIT. // Source: calculator.go // Package util is a generated GoMock package. package util import ( reflect "reflect" gomock "github.com/golang/mock/gomock" ) // MockCalculator is a mock of Calculator interface. type MockCalculator struct { ctrl *gomock.Controller recorder *MockCalculatorMockRecorder } // MockCalculatorMockRecorder is the mock recorder for MockCalculator. type MockCalculatorMockRecorder struct { mock *MockCalculator } // NewMockCalculator creates a new mock instance. func NewMockCalculator(ctrl *gomock.Controller) *MockCalculator { mock := &MockCalculator{ctrl: ctrl} mock.recorder = &MockCalculatorMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. func (m *MockCalculator) EXPECT() *MockCalculatorMockRecorder { return m.recorder } // Add mocks base method. func (m *MockCalculator) Add(a, b int) int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Add", a, b) ret0, _ := ret[0].(int) return ret0 } // Add indicates an expected call of Add. func (mr *MockCalculatorMockRecorder) Add(a, b interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockCalculator)(nil).Add), a, b) } // Subtract mocks base method. func (m *MockCalculator) Subtract(a, b int) int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Subtract", a, b) ret0, _ := ret[0].(int) return ret0 } // Subtract indicates an expected call of Subtract. func (mr *MockCalculatorMockRecorder) Subtract(a, b interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Subtract", reflect.TypeOf((*MockCalculator)(nil).Subtract), a, b) } ``` ### <span style="font-size:15px">**3、mock控制器定義**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mock 控制器通過 NewController 接口生成,是 mock 生態系統的頂層控制,它定義了 mock 對象的作用域和生命周期,以及它們的期望。多個協程同時調用控制器的方法是安全的。當用例結束后,控制器會檢查所有剩余期望的調用是否滿足條件。 ``` ctrl?:=?NewController(t) defer?ctrl.Finish() ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mock 對象創建時需要注入控制器,如果有多個 mock 對象則注入同一個控制器,如下所示: ``` ctl := gomock.NewController(t) defer ctl.Finish() mockCalculator := NewMockCalculator(ctl) ``` ### <span style="font-size:15px">**4、mock 對象的行為注入**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;對于 mock 對象的行為注入,控制器是通過 map 來維護的,一個方法對應 map 的一項。因為一個方法在一個用例中可能調用多次,所以 map 的值類型是數組切片。當 mock 對象進行行為注入時,控制器會將行為 Add。當該方法被調用時,控制器會將該行為 Remove。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通過生成的mock類提供的EXPECT方法進行mock方法、參數和期望返回行為進行注入 ``` mockCalculator.EXPECT().Add(1, 2).Return(4).MaxTimes(1) ``` ### <span style="font-size:15px">**5、單測完整示例**</span> ``` package util import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "testing" ) func TestAddByMock(t *testing.T) { ctl := gomock.NewController(t) defer ctl.Finish() mockCalculator := NewMockCalculator(ctl) mockCalculator.EXPECT().Add(1, 2).Return(4).MaxTimes(1) m := &MyCalculator{} if !assert.EqualValues(t, 3, m.Add(1, 2)) { // mock設置方法返回值為4,因此斷言失敗 t.Fail() } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看