<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智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## <span style="font-size:15px">**一、說明**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;httpmock是一款用來模擬http接口請求的工具 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;github地址:`https://github.com/jarcoal/httpmock` 基本使用步驟: * 啟動httpmock環境:httpmock.Activate方法 * 路由規則注冊:httpmock.RegisterResponder方法。此時,http client發起的請求如果匹配到http mock中注冊的規則,則會返回mock response * 在defer里面調用DeactivateAndReset結束mock 官方示例: ``` func TestFetchArticles(t *testing.T) { httpmock.Activate() defer httpmock.DeactivateAndReset() // Exact URL match httpmock.RegisterResponder("GET", "https://api.mybiz.com/articles", httpmock.NewStringResponder(200, `[{"id": 1, "name": "My Great Article"}]`)) // Regexp match (could use httpmock.RegisterRegexpResponder instead) httpmock.RegisterResponder("GET", `=~^https://api\.mybiz\.com/articles/id/\d+\z`, httpmock.NewStringResponder(200, `{"id": 1, "name": "My Great Article"}`)) // do stuff that makes a request to articles ... // get count info httpmock.GetTotalCallCount() // get the amount of calls for the registered responder info := httpmock.GetCallCountInfo() info["GET https://api.mybiz.com/articles"] // number of GET calls made to https://api.mybiz.com/articles info["GET https://api.mybiz.com/articles/id/12"] // number of GET calls made to https://api.mybiz.com/articles/id/12 info[`GET =~^https://api\.mybiz\.com/articles/id/\d+\z`] // number of GET calls made to https://api.mybiz.com/articles/id/<any-number> } ``` ## <span style="font-size:15px">**二、使用示例**</span> 1、示例1:mock固定路由,并mock 字符串響應body ``` func getAPIResponse(url string) (string, error) { var err error request, err := http.NewRequest(http.MethodGet, url, http.NoBody) if err != nil { return "", err } myClient := &http.Client{} response, err := myClient.Do(request) if err != nil { return "", err } defer response.Body.Close() if response.StatusCode != 200 { return "", errors.New("response not 200!") } bodyBytes, err := ioutil.ReadAll(response.Body) if err != nil { return "", err } return string(bodyBytes), nil } ``` ``` func TestGetAPIResponse(t *testing.T) { var api string var responseBody string var err error // http mock test var mockResponse string api = "http://www.baidu.com" mockResponse = "mock response body" httpmock.Activate() defer httpmock.DeactivateAndReset() httpmock.RegisterResponder("GET", api, httpmock.NewStringResponder(200, string(mockResponse))) fmt.Println(httpmock.GetCallCountInfo()) responseBody, err = getAPIResponse(api) if err != nil { t.Errorf("second test failed! err: %v", err) } if responseBody != mockResponse { t.Errorf("second test failed! Unexpect response!") } } === RUN TestGetAPIResponse map[GET http://www.baidu.com:0] --- PASS: TestGetAPIResponse (0.00s) PASS ok sangfor.com/xdr/xlink/common/util 0.041s ``` 2、示例2:mock固定路由,并mock json響應body ``` type Response struct { Message string `json:"message"` } func TestHttpMock(t *testing.T) { httpmock.Activate() url := "http://xxxxxx" responder, _ := httpmock.NewJsonResponder(http.StatusOK, Response{Message: "success"}) httpmock.RegisterResponder("GET", url, responder) response := &Response{} client := http.Client{} req, err := http.NewRequest(http.MethodGet, url, http.NoBody) res, _ := client.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) err = json.Unmarshal(body, &response) if err != nil { t.Errorf("fail") } fmt.Println(response.Message) } ``` 3、示例3:自定義mock http response 返回 ``` api = "http://www.baidu.com/fail" httpmock.RegisterResponder("GET", api, func(r *http.Request) (*http.Response, error) { return &http.Response{ Status: strconv.Itoa(200), StatusCode: 200, ContentLength: -1, }, errors.New("fail error!") }) responseBody, err = getAPIResponse(api) if err == nil { t.Errorf("request fail test failed! err: %v", err) } if responseBody != "" { t.Errorf("request fail test failed! Unexpect response! response: %s", responseBody) } ``` 4、示例4:對設置Transport的http client進行mock 對于設置了Transport的http請求,可以使用`httpmock.ActivateNonDefaul `方法進行mock,并支持傳入對應的client。 ``` func TestHttpTransportMock(t *testing.T) { response := &Response{} client := http.Client{ Timeout: time.Second * 3, Transport: &http.Transport{ DisableKeepAlives: true, }, } httpmock.ActivateNonDefault(&client) defer httpmock.DeactivateAndReset() url := "http://xxxxxx" responder, _ := httpmock.NewJsonResponder(http.StatusOK, &Response{Message: "success"}) httpmock.RegisterResponder("GET", url, responder) httpmock.NewMockTransport() req, err := http.NewRequest(http.MethodGet, url, http.NoBody) if err != nil { t.Errorf("failed to create request: %v", err) return } res, err := client.Do(req) if err != nil { t.Errorf("failed to perform request: %v", err) return } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { t.Errorf("failed to read response body: %v", err) return } err = json.Unmarshal(body, &response) if err != nil { t.Errorf("failed to unmarshal response: %v", err) return } fmt.Println(response.Message) } ``` 4、示例5:對設置Transport的http client進行mock不成功的情況 ``` func getApiResponse(url string) (*openapi, error) { client := http.Client{ Timeout: time.Second * 3, Transport: &http.Transport{ DisableKeepAlives: true, }, } log.Infof("client:%v", &client) req, err := http.NewRequest(http.MethodGet, url , http.NoBody) if err != nil { return nil, fmt.Errorf(" err=%v", err) } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf(" client.Do err=%v", err) } defer resp.Body.Close() buff, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf(" body err=%v", err) } temp := &openapiAKSK{} err = json.Unmarshal(buff, temp) if err != nil { return nil, fmt.Errorf("json.Unmarshal err=%v", err) } return temp, nil } // 編寫單測 func TestGetApiResponse(t *testing.T) { client := http.Client{ Timeout: time.Second * 3, Transport: &http.Transport{ DisableKeepAlives: true, }, } log.Infof("client1:%v", &client) httpmock.ActivateNonDefault(&client) defer httpmock.DeactivateAndReset() resp, _ := httpmock.NewJsonResponder(200, Response{Data: struct { AK string `json:"ak"` }(struct{ AK string }{AK: "mockedAK"})}) httpmock.RegisterResponder( "GET", "http://openapi.platform.svc.cluster.local", resp) result, err := getApiResponse("http://openapi.platform.svc.cluster.local") if err != nil { t.Errorf("Expected no error, but got %v", err) } if result.Data.AK != "mockedAK" { t.Errorf("Expected to be 'mockedAK', but got %s", result.Data.AK) } } === RUN TestGetApiResponse devicesingleloginHandler_test.go:85: Expected no error, but got devsso getOpenapiAKSK client.Do err=Get "http://openapi.platform.svc.cluster.local": dial tcp: lookup openapi.platform.svc.cluster.local: no such host --- FAIL: TestGetApiResponse(0.20s) panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;執行結果會發現,單測中已經使用了`httpmock.ActivateNonDefaul `,并且設置了一樣的Transport,執行失敗。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;這是因為代碼邏輯和單測中,分別初始化了http client,這兩個實際上不是同一個client。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通過日志打印可以看出,兩個client的指針地址并不相同。 ``` 2023/12/26 15:48:31 consolewriter.go:51: {"msg":"client1:\u0026{0xc0000de3c0 \u003cnil\u003e \u003cnil\u003e 3s}"} map[GET http://openapi.platform.svc.cluster.local:0] 2023/12/26 15:48:31 consolewriter.go:51: {"msg":"client:\u0026{0xc0000de500 \u003cnil\u003e \u003cnil\u003e 3s}"} ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;因此,需要把代碼修改為client傳入的方式,確保代碼和單測可以使用同一個client。 ``` func getApiResponse(url string, client *http.Client) (*openapi, error) { req, err := http.NewRequest(http.MethodGet, url , http.NoBody) if err != nil { return nil, fmt.Errorf(" err=%v", err) } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf(" client.Do err=%v", err) } defer resp.Body.Close() buff, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf(" body err=%v", err) } temp := &openapiAKSK{} err = json.Unmarshal(buff, temp) if err != nil { return nil, fmt.Errorf("json.Unmarshal err=%v", err) } return temp, nil } // 編寫單測 func TestGetApiResponse(t *testing.T) { client := http.Client{ Timeout: time.Second * 3, Transport: &http.Transport{ DisableKeepAlives: true, }, } log.Infof("client1:%v", &client) httpmock.ActivateNonDefault(&client) defer httpmock.DeactivateAndReset() resp, _ := httpmock.NewJsonResponder(200, Response{Data: struct { AK string `json:"ak"` }(struct{ AK string }{AK: "mockedAK"})}) httpmock.RegisterResponder( "GET", "http://openapi.platform.svc.cluster.local", resp) result, err := getApiResponse("http://openapi.platform.svc.cluster.local", client) if err != nil { t.Errorf("Expected no error, but got %v", err) } if result.Data.AK != "mockedAK" { t.Errorf("Expected to be 'mockedAK', but got %s", result.Data.AK) } } ```
                  <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>

                              哎呀哎呀视频在线观看