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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 使用標準庫進行模擬 在Go中,模擬通常意味著實現具有測試版本的接口,該測試版本允許從測試中控制運行時行為。它也可以指模擬函數和方法,我們將探索如何實現它。示例中使用的Patch和Restore函數可以在https://play.golang.org/p/oLF1XnRX3C 找到。 包含大量分支條件或深度嵌套邏輯的代碼可能很難測試,最后測試往往更加效果很差。這是因為開發人員需要在其測試中跟蹤很多模擬對象,返回值和狀態。 ### 實踐 1. 建立 mock.go: ``` package mocking // DoStuffer 是一個簡單的接口 type DoStuffer interface { DoStuff(input string) error } ``` 2. 建立 patch.go: ``` package mocking import "reflect" // Restorer是一個可用于恢復先前狀態的函數 type Restorer func() // Restore存儲了之前的狀態 func (r Restorer) Restore() { r() } // Patch將給定目標指向的值設置為給定值,并返回一個函數以將其恢復為原始值。 該值必須可分配給目標的元素類型。 func Patch(dest, value interface{}) Restorer { destv := reflect.ValueOf(dest).Elem() oldv := reflect.New(destv.Type()).Elem() oldv.Set(destv) valuev := reflect.ValueOf(value) if !valuev.IsValid() { // 對于目標類型不可用的情況,這種解決方式并不優雅 valuev = reflect.Zero(destv.Type()) } destv.Set(valuev) return func() { destv.Set(oldv) } } ``` 3. 建立 exec.go: ``` package mocking import "errors" var ThrowError = func() error { return errors.New("always fails") } func DoSomeStuff(d DoStuffer) error { if err := d.DoStuff("test"); err != nil { return err } if err := ThrowError(); err != nil { return err } return nil } ``` 4. 建立 mock_test.go: ``` package mocking type MockDoStuffer struct { // 使用閉包模擬 MockDoStuff func(input string) error } func (m *MockDoStuffer) DoStuff(input string) error { if m.MockDoStuff != nil { return m.MockDoStuff(input) } // 如果我們不模擬輸入,就返回一個常見的情況 return nil } ``` 5. 建立 exec_test.go: ``` package mocking import ( "errors" "testing" ) func TestThrowError(t *testing.T) { tests := []struct { name string wantErr bool }{ {"base-case", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := ThrowError(); (err != nil) != tt.wantErr { t.Errorf("DoSomeStuff() error = %v, wantErr %v", err, tt.wantErr) } }) } } func TestDoSomeStuff(t *testing.T) { tests := []struct { name string DoStuff error ThrowError error wantErr bool }{ {"base-case", nil, nil, false}, {"DoStuff error", errors.New("failed"), nil, true}, {"ThrowError error", nil, errors.New("failed"), true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // 使用模擬結構來模擬接口 d := MockDoStuffer{} d.MockDoStuff = func(string) error { return tt.DoStuff } // 模擬聲明為變量的函數對func A()不起作用,必須是var A = func() defer Patch(&ThrowError, func() error { return tt.ThrowError }).Restore() if err := DoSomeStuff(&d); (err != nil) != tt.wantErr { t.Errorf("DoSomeStuff() error = %v, wantErr %v", err, tt.wantErr) } }) } } ``` 6. 運行go test: ``` PASS ok github.com/agtorre/go-cookbook/chapter8/mocking 0.006s ``` ### 說明 無論是使用errors.New,fmt.Errorf還是自定義錯誤,最重要的是不應該在代碼中不處理錯誤。這些定義錯誤的不同方法提供了很大的靈活性。例如,你可以在結構中添加額外的函數,以進一步檢查錯誤并將接口轉換為調用函數中的錯誤類型,以獲得一些額外的功能。 接口本身非常簡單,唯一的要求是返回一個有效的字符串。(在測試中明顯將其復雜化了)這樣的測試保證對某些要求嚴格的應用程序同樣可用。 * * * * 學識淺薄,錯誤在所難免。歡迎在群中就本書提出修改意見,以饗后來者,長風拜謝。 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>

                              哎呀哎呀视频在线观看