亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我可以為我的測試用例編寫我自己版本的 go 的 http client.Do() 函數嗎?

我可以為我的測試用例編寫我自己版本的 go 的 http client.Do() 函數嗎?

Go
九州編程 2022-11-23 20:25:10
我有一個名為 user-service.go 的文件和相應的測試文件,名為 user-service_test.go。當我試圖獲得完整的代碼覆蓋率時,我正在努力讓一些錯誤條件真正發生。這是函數:GetOrCreateByAccessToken()//GetOrCreateByAccessToken gets a user from the database with the given access tokenfunc (s *service) GetOrCreateByAccessToken(aT string, client *Client) (*user.User, fcerr.FCErr) {var currentUser user.OauthUserreq, err := http.NewRequest("GET", "https://openidconnect.googleapis.com/v1/userinfo?access_token="+aT, nil)if err != nil {    return nil, fcerr.NewInternalServerError("Error when setting up the network request")}response, err := client.httpClient.Do(req)if err != nil {    fmt.Println("error when getting the userinfo with the access token")    return nil, fcerr.NewInternalServerError("Error when trying to verify user identity")}defer response.Body.Close()contents, err := io.ReadAll(response.Body)if err != nil {    return nil, fcerr.NewInternalServerError("Error when trying to read response from Google about user identity")}我對測試的主要控制是我可以傳入 *Client。這是測試用例的一部分,我想讓 io.ReadAll 拋出一個錯誤:h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {    //manually return the message google would return on an actual request    w.Write([]byte(googleAPIOKResponse))})//Call the testHTTPClient() function defined in the test file to substitute my own HandlerFunchttpClient, teardown := testHTTPClient(h)defer teardown()//Call the real NewClient() from my user-service.goclient := NewClient()//Substitute the default httpClient for the one I've just set up.client.httpClient = httpClientresultingUser, err := userService.GetOrCreateByAccessToken(nU.AccessToken, client)assert.Nil(t, resultingUser)assert.NotNil(t, err)assert.Equal(t, http.StatusInternalServerError, err.Status())有什么地方我可以編寫自己的 .Do() 方法版本,該方法會在響應中放置一些內容,這會導致 io.ReadAll 返回錯誤?或者是否有更好的方法來僅使用我已經使用的預烘焙響應文本來實現錯誤?
查看完整描述

1 回答

?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

沒有一種方法可以替代 Do 方法,但是有一種方法可以實現您的目標。


創建一個返回任意響應主體的往返類型:


type respondWithReader struct{ body io.Reader }


func (rr respondWithReader) RoundTrip(req *http.Request) (*http.Response, error) {

    return &http.Response{

        Proto:      "HTTP/1.0",

        ProtoMajor: 1,

        Header:     make(http.Header),

        Close:      true,

        Body:       ioutil.NopCloser(rr.body),

    }, nil


}

創建一個失敗的 io.Reader:


var errReadFail = errors.New("blah!")


type failReader int


func (failReader) Read([]byte) (int, error) {

    return 0, errReadFail

}

將 stock 客戶端與上面的傳輸和閱讀器一起使用:


c := http.Client{Transport: respondWithReader{body: failReader(0)}}

resp, err := c.Get("http://whatever.com")

if err != nil {

    t.Error(err)

}

defer resp.Body.Close()


// ReadAll returns errReadFail

_, err = ioutil.ReadAll(resp.Body)

if err != errReadFail {

    t.Errorf("got err %v, expect %v", err, errReadFail)

}


查看完整回答
反對 回復 2022-11-23
  • 1 回答
  • 0 關注
  • 97 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號