<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 使用Mockgen包 前面的小節我們使用了自行模擬的方式。當你需要面對很多的接口時,這么干會變得極為麻煩且極易發生錯誤。這是自動化測試的意義所在。本節我們使用 github.com/golang/mock/gomock ,該庫提供了一組模擬對象,可以與接口測試結合使用。 ### 實踐 1.獲取第三方庫: ``` go get github.com/golang/mock/ ``` 2. 建立 interface.go: ``` package mockgen type GetSetter interface { Set(key, val string) error Get(key string) (string, error) } ``` 3. 運行命令行建立 mocks.go: ``` mockgen -destination internal/mocks.go -package internal github.com/agtorre/go-cookbook/chapter8/mockgen GetSetter ``` ``` // Automatically generated by MockGen. DO NOT EDIT! // Source: github.com/agtorre/go-cookbook/chapter8/mockgen (interfaces: GetSetter) package internal import ( gomock "github.com/golang/mock/gomock" ) // Mock of GetSetter interface type MockGetSetter struct { ctrl *gomock.Controller recorder *_MockGetSetterRecorder } // Recorder for MockGetSetter (not exported) type _MockGetSetterRecorder struct { mock *MockGetSetter } func NewMockGetSetter(ctrl *gomock.Controller) *MockGetSetter { mock := &MockGetSetter{ctrl: ctrl} mock.recorder = &_MockGetSetterRecorder{mock} return mock } func (_m *MockGetSetter) EXPECT() *_MockGetSetterRecorder { return _m.recorder } func (_m *MockGetSetter) Get(_param0 string) (string, error) { ret := _m.ctrl.Call(_m, "Get", _param0) ret0, _ := ret[0].(string) ret1, _ := ret[1].(error) return ret0, ret1 } func (_mr *_MockGetSetterRecorder) Get(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Get", arg0) } func (_m *MockGetSetter) Set(_param0 string, _param1 string) error { ret := _m.ctrl.Call(_m, "Set", _param0, _param1) ret0, _ := ret[0].(error) return ret0 } func (_mr *_MockGetSetterRecorder) Set(arg0, arg1 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Set", arg0, arg1) } ``` 4. 建立 exec.go: ``` package mockgen // Controller 這個結構體演示了一種初始化接口的方式 type Controller struct { GetSetter } // GetThenSet 檢查值是否已設置。如果沒有設置就將其設置 func (c *Controller) GetThenSet(key, value string) error { val, err := c.Get(key) if err != nil { return err } if val != value { return c.Set(key, value) } return nil } ``` 5. 建立 interface_test.go: ``` package mockgen import ( "errors" "testing" "github.com/agtorre/go-cookbook/chapter8/mockgen/internal" "github.com/golang/mock/gomock" ) func TestExample(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockGetSetter := internal.NewMockGetSetter(ctrl) var k string mockGetSetter.EXPECT().Get("we can put anything here!").Do(func(key string) { k = key }).Return("", nil) customError := errors.New("failed this time") mockGetSetter.EXPECT().Get(gomock.Any()).Return("", customError) if _, err := mockGetSetter.Get("we can put anything here!"); err != nil { t.Errorf("got %#v; want %#v", err, nil) } if k != "we can put anything here!" { t.Errorf("bad key") } if _, err := mockGetSetter.Get("key"); err == nil { t.Errorf("got %#v; want %#v", err, customError) } } ``` 6. 建立 exec_test.go: ``` package mockgen import ( "errors" "testing" "github.com/agtorre/go-cookbook/chapter8/mockgen/internal" "github.com/golang/mock/gomock" ) func TestController_Set(t *testing.T) { tests := []struct { name string getReturnVal string getReturnErr error setReturnErr error wantErr bool }{ {"get error", "value", errors.New("failed"), nil, true}, {"value match", "value", nil, nil, false}, {"no errors", "not set", nil, nil, false}, {"set error", "not set", nil, errors.New("failed"), true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockGetSetter := internal.NewMockGetSetter(ctrl) mockGetSetter.EXPECT().Get("key").AnyTimes().Return(tt.getReturnVal, tt.getReturnErr) mockGetSetter.EXPECT().Set("key", gomock.Any()).AnyTimes().Return(tt.setReturnErr) c := &Controller{ GetSetter: mockGetSetter, } if err := c.GetThenSet("key", "value"); (err != nil) != tt.wantErr { t.Errorf("Controller.Set() error = %v, wantErr %v", err, tt.wantErr) } }) } } ``` ### 說明 生成的模擬對象允許測試預定的參數,調用函數的次數以及返回的內容,并且允許我們設置其他工作流程。interface_test.go文件展示了在線調用它們時使用模擬對象的一些示例。 通常,測試看起來更像exec_test.go,我們希望攔截由實際代碼執行的接口函數調用,并在測試時更改它們的行為。 exec_test.go文件還展示了如何在表驅動的測試環境中使用模擬對象。Any()函數意味著模擬函數可以被調用零次或多次,這對于代碼提前終止的情況非常有用。 示例演示的最后一個技巧是將模擬對象粘貼到內部包中。當需要模擬在自己之外的包中聲明的函數時,這非常有用。 這允許在非_test.go文件中定義這些方法,但不允許將它們導出到庫的情況。通常,使用與當前編寫的測試相同的包名稱將模擬對象粘貼到_test.go文件中更容易。 * * * * 學識淺薄,錯誤在所難免。歡迎在群中就本書提出修改意見,以饗后來者,長風拜謝。 Golang中國(211938256) beego實戰(258969317) Go實踐(386056972)
                  <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>

                              哎呀哎呀视频在线观看