我有一個名為 user-service.go 的檔案和相應的測驗檔案,名為 user-service_test.go。當我試圖獲得完整的代碼覆寫率時,我正在努力讓一些錯誤情況真正發生。
這是函式:GetOrCreateByAccessToken()
//GetOrCreateByAccessToken gets a user from the database with the given access token
func (s *service) GetOrCreateByAccessToken(aT string, client *Client) (*user.User, fcerr.FCErr) {
var currentUser user.OauthUser
req, 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 HandlerFunc
httpClient, teardown := testHTTPClient(h)
defer teardown()
//Call the real NewClient() from my user-service.go
client := NewClient()
//Substitute the default httpClient for the one I've just set up.
client.httpClient = httpClient
resultingUser, err := userService.GetOrCreateByAccessToken(nU.AccessToken, client)
assert.Nil(t, resultingUser)
assert.NotNil(t, err)
assert.Equal(t, http.StatusInternalServerError, err.Status())
有沒有什么地方我可以撰寫自己的 .Do() 方法版本,它會在回應中放入一些內容,從而導致 io.ReadAll 回傳錯誤?或者有沒有更好的方法來使用我已經在使用的預烘焙回應文本來實作錯誤?
uj5u.com熱心網友回復:
沒有辦法替代 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
}
使用帶有上述傳輸和閱讀器的股票客戶端:
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)
}
在 Go 操場上運行測驗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/452777.html
