为了账号安全,请及时绑定邮箱和手机立即绑定

我应该如何对包含对外部服务的 GET 调用的方法进行单元测试

我应该如何对包含对外部服务的 GET 调用的方法进行单元测试

Go
偶然的你 2023-08-07 14:32:25
我正在使用 Gin Gonic 在 Go API 中编写单元测试。这是我的代码。func getKeys(c *gin.Context) {    var meters []models.Meter    metadataOperation, err := metadata.GetOperation("AC123456")    if err != nil {        sendInternalError(err, c)        return    }    meter, err := metadata.GetMeter("12345")    // Other instructions    // ...    // operation = ...    c.JSON(http.StatusOK, operation)}这是 GetOperation 方法:func GetOperation(operationID string) (Operation, error) {    var operation Operation    var url = metadataAPIURL + "/v2/operations/" + operationID    tr := &http.Transport{        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},    }    client := &http.Client{Transport: tr}    req, err := http.NewRequest("GET", url, nil)    if err != nil {        return Operation{}, err    }    req.SetBasicAuth(metadataAPIUser, metadataAPIPassword)    res, err := client.Do(req)    if err != nil {        return Operation{}, err    }    if res.StatusCode != 200 {        return Operation{}, errors.New(res.Status)    }    err = json.NewDecoder(res.Body).Decode(&operation)    if err != nil {        return Operation{}, err    }    return operation, nil}事情是metadata.GetOperation("AC123456")向外部服务发出 GET 请求。据我了解单元测试,我不能有任何外部依赖项。就我而言,测试正在通过,但它正在向我的生产服务器发出 GET 请求,这不是想要的结果。如果我想使用模拟,我应该有一个接口,并在依赖关系和模拟之间切换。测试方法应该很棒GetOperation,但是对于getKeys方法,我似乎不清楚应该如何做。遇到这种情况我该怎么处理呢?谁能给我一个关于这个案例的例子/教程。
查看完整描述

2 回答

?
繁星淼淼

TA贡献1775条经验 获得超11个赞

我正在使用 Gin Gonic 在 Go API 中编写单元测试。


这是我的代码。


func getKeys(c *gin.Context) {

    var meters []models.Meter


    metadataOperation, err := metadata.GetOperation("AC123456")

    if err != nil {

        sendInternalError(err, c)

        return

    }

    meter, err := metadata.GetMeter("12345")

    // Other instructions

    // ...

    // operation = ...

    c.JSON(http.StatusOK, operation)

}

这是 GetOperation 方法:


func GetOperation(operationID string) (Operation, error) {

    var operation Operation

    var url = metadataAPIURL + "/v2/operations/" + operationID

    tr := &http.Transport{

        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},

    }

    client := &http.Client{Transport: tr}

    req, err := http.NewRequest("GET", url, nil)


    if err != nil {

        return Operation{}, err

    }

    req.SetBasicAuth(metadataAPIUser, metadataAPIPassword)

    res, err := client.Do(req)

    if err != nil {

        return Operation{}, err

    }

    if res.StatusCode != 200 {

        return Operation{}, errors.New(res.Status)

    }

    err = json.NewDecoder(res.Body).Decode(&operation)

    if err != nil {

        return Operation{}, err

    }

    return operation, nil

}

事情是metadata.GetOperation("AC123456")向外部服务发出 GET 请求。


据我了解单元测试,我不能有任何外部依赖项。


就我而言,测试正在通过,但它正在向我的生产服务器发出 GET 请求,这不是想要的结果。


如果我想使用模拟,我应该有一个接口,并在依赖关系和模拟之间切换。


测试方法应该很棒GetOperation,但是对于getKeys方法,我似乎不清楚应该如何做。


遇到这种情况我该怎么处理呢?谁能给我一个关于这个案例的例子/教程。


查看完整回答
反对 回复 2023-08-07
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

据我所知,在单元测试中有两种常见的方法可以做到这一点。

首先是模拟请求(例如创建Requester接口或类似的东西来包装真正的 GET 请求),然后在单元测试中将其替换为模拟对象。这称为依赖注入。

第二种方法是使用net/http/httptest并替换metadataAPIURL为 localhost URL 来运行测试服务器。


查看完整回答
反对 回复 2023-08-07
  • 2 回答
  • 0 关注
  • 124 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信