我可以为我的测试用例编写我自己版本的 go 的 http client.Do() 函数吗?

杰森拉德

我有一个名为 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 返回错误?或者有没有更好的方法来使用我已经在使用的预烘焙响应文本来实现错误?

宗博

没有替代 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 操场上运行测试

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用go http client Do方法时,httpResponse和错误可以不同时为nil吗?

我可以使用Jasmine spy编写AngularJS服务的测试用例吗?

如何为我的函数编写测试用例?的PHP

我可以为自己的变量调用$ .fn函数吗?

我可以在测试用例中模拟功能输入吗?

我可以为无效寿命编写测试吗?

我可以编写Apache http关机脚本或使用AutoIT制作一个可以为我重新启动它的工具吗?

禁用通用名称验证-Go HTTP Client

匿名go函数可以调用自身吗?

可以扩展go struct构造函数吗?

我们可以使用 Go 语言编写的 lambda 函数向 SNS 主题发布消息吗?

可以在2015年使用Http Client登录Facebook登录吗?

我应该为同一服务的不同分支编写不同的测试用例吗?

我可以在Robot Framework中按测试用例重新运行失败的测试吗?

Go的http服务器可以编译打字稿吗?

我们可以为Go中的错误创建子类型吗?

我可以自己编写命令吗?

HTTP ResponseWriter的写函数是否可以在Go中缓冲?

我可以创建自己的根证书以用于与Go进行SSL连接吗?这样安全吗?

我可以为 2.x 版运行时的基于 http 触发器的 azure 函数配置自定义名称吗?

Java程序具有Linux方法-我可以在它们上运行Junit测试用例吗?

我可以在TestNG测试用例上指定类范围的组吗?

我可以将集合传递给DUnitX中的测试用例吗?

我可以获取机器人框架内测试用例步骤的统计信息吗?

我可以使用robot.api 获取失败的测试用例名称吗?

我可以在azure函数中实现异步“触发并忘记” HTTP触发器吗?

我可以在 Google Cloud Workflows 中为 http.post 函数指定凭据吗?

我可以在函数中测试变量吗?

我是打字稿、反应和单元测试的新手。如何用玩笑为以下函数编写测试用例?