duanlu4371
2018-01-12 14:24
浏览 370
已采纳

如何在Golang中为HTTP请求编写单元测试?

I don't know how to test the http response given in the code below.

func getVolDetails(volName string, obj interface{}) error {
    addr := os.Getenv("MAPI_ADDR")
    if addr == "" {
        err := errors.New("MAPI_ADDR environment variable not set")
        fmt.Println(err)
        return err
    }
    url := addr + "/path/to/somepage/" + volName
    client := &http.Client{
        Timeout: timeout,
    }
    resp, err := client.Get(url)
    if resp != nil {
        if resp.StatusCode == 500 {
            fmt.Printf("VSM %s not found
", volName)
            return err
        } else if resp.StatusCode == 503 {
            fmt.Println("server not reachable")
            return err
        }
    } else {
        fmt.Println("server not reachable")
        return err
    }

    if err != nil {
        fmt.Println(err)
        return err
    }
    defer resp.Body.Close()

    return json.NewDecoder(resp.Body).Decode(obj)
}

With the help of some references i wrote unit test for this which is given below

func TestGetVolDetails(t *testing.T) {
    var (
        volume v1.Volume
        server *httptest.Server
    )
    tests := map[string]struct {
        volumeName string
        err        error
    }{
        "TestOne": {"vol", nil},
    }
    for name, tt := range tests {
        t.Run(name, func(t *testing.T) {
            response := `{"metadata":{"annotations":{"vsm.openebs.io/targetportals":"10.98.65.136:3260","vsm.openebs.io/cluster-i    ps":"10.98.65.136","openebs.io/jiva-iqn":"iqn.2016-09.com.openebs.jiva:vol","deployment.kubernetes.io/revision":"1","openebs.io/storage-pool"    :"default","vsm.openebs.io/replica-count":"1","openebs.io/jiva-controller-status":"Running","openebs.io/volume-monitor":"false","openebs.io/r    eplica-container-status":"Running","openebs.io/jiva-controller-cluster-ip":"10.98.65.136","openebs.io/jiva-replica-status":"Running","vsm.ope    nebs.io/iqn":"iqn.2016-09.com.openebs.jiva:vol","openebs.io/capacity":"2G","openebs.io/jiva-controller-ips":"10.36.0.6","openebs.io/jiva-repl    ica-ips":"10.36.0.7","vsm.openebs.io/replica-status":"Running","vsm.openebs.io/controller-status":"Running","openebs.io/controller-container-    status":"Running","vsm.openebs.io/replica-ips":"10.36.0.7","openebs.io/jiva-target-portal":"10.98.65.136:3260","openebs.io/volume-type":"jiva    ","openebs.io/jiva-replica-count":"1","vsm.openebs.io/volume-size":"2G","vsm.openebs.io/controller-ips":"10.36.0.6"},"creationTimestamp":null    ,"labels":{},"name":"vol"},"status":{"Message":"","Phase":"Running","Reason":""}}`
            server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                fmt.Fprintln(w, response)
            }))
            os.Setenv("MAPI_ADDR", "http://"+server.URL)
            if got := GetVolDetails(tt.volumeName, &volume); got != tt.err {
                t.Fatalf("GetVolDetails(%v) => got %v, want %v ", tt.volumeName, got, tt.err)
            }
            defer server.Close()
        })
    }
}

Where response is the response i'm getting from the server. This gives me always different errors. got invalid character '<' looking for beginning of value, want <nil>

got Get http://www.HugeDomains.com: net/http: request canceled (Client.Timeout exceeded while awaiting headers), want <nil>

What am I doing wrong?

Edit:

Updated the code with SOME_ADDR to MAPI_ADDR which was done while posting question. Please don't be confused with that, problem remains as it is.

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • duanhuan3012 2018-01-12 16:02
    已采纳

    You are getting a timeout but you are not specifying what timeout is set to. I suspect that this is not a time.Duration object and that is causing your timeout. There are a few other issues as well. To get this to work I did:

    1. Change the function being called in the test to getVolDetails to match the code (not the lower case g)
    2. Set the Timeout when creating the client to Timeout: time.Second * 10
    3. Remove the "http://"+ from the os.Setenv("MAPI_ADDR", "http://"+server.URL) line

    Corrected code is:

    var timeout time.Duration = time.Second * 1000
    
    func getVolDetails(volName string, obj interface{}) error {
        addr := os.Getenv("MAPI_ADDR")
        if addr == "" {
            err := errors.New("MAPI_ADDR environment variable not set")
            fmt.Println(err)
            return err
        }
        url := addr + "/path/to/somepage/" + volName
        client := &http.Client{
            Timeout: timeout,
        }
        resp, err := client.Get(url)
        if resp != nil {
            if resp.StatusCode == 500 {
                fmt.Printf("VSM %s not found
    ", volName)
                return err
            } else if resp.StatusCode == 503 {
                fmt.Println("server not reachable")
                return err
            }
        } else {
            fmt.Println("server not reachable")
            return err
        }
    
        if err != nil {
            fmt.Println(err)
            return err
        }
        defer resp.Body.Close()
    
        return json.NewDecoder(resp.Body).Decode(obj)
    }
    

    and test:

    func TestGetVolDetails(t *testing.T) {
        var (
            volume v1.Volume
            server *httptest.Server
        )
        tests := map[string]struct {
            volumeName string
            err        error
        }{
            "TestOne": {"vol", nil},
        }
        for name, tt := range tests {
            t.Run(name, func(t *testing.T) {
                response := `{"metadata":{"annotations":{"vsm.openebs.io/targetportals":"10.98.65.136:3260","vsm.openebs.io/cluster-i    ps":"10.98.65.136","openebs.io/jiva-iqn":"iqn.2016-09.com.openebs.jiva:vol","deployment.kubernetes.io/revision":"1","openebs.io/storage-pool"    :"default","vsm.openebs.io/replica-count":"1","openebs.io/jiva-controller-status":"Running","openebs.io/volume-monitor":"false","openebs.io/r    eplica-container-status":"Running","openebs.io/jiva-controller-cluster-ip":"10.98.65.136","openebs.io/jiva-replica-status":"Running","vsm.ope    nebs.io/iqn":"iqn.2016-09.com.openebs.jiva:vol","openebs.io/capacity":"2G","openebs.io/jiva-controller-ips":"10.36.0.6","openebs.io/jiva-repl    ica-ips":"10.36.0.7","vsm.openebs.io/replica-status":"Running","vsm.openebs.io/controller-status":"Running","openebs.io/controller-container-    status":"Running","vsm.openebs.io/replica-ips":"10.36.0.7","openebs.io/jiva-target-portal":"10.98.65.136:3260","openebs.io/volume-type":"jiva    ","openebs.io/jiva-replica-count":"1","vsm.openebs.io/volume-size":"2G","vsm.openebs.io/controller-ips":"10.36.0.6"},"creationTimestamp":null    ,"labels":{},"name":"vol"},"status":{"Message":"","Phase":"Running","Reason":""}}`
                server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                    fmt.Fprintln(w, response)
                }))
                os.Setenv("MAPI_ADDR", server.URL)
                if got := getVolDetails(tt.volumeName, &volume); got != tt.err {
                    t.Fatalf("GetVolDetails(%v) => got %v, want %v ", tt.volumeName, got, tt.err)
                }
                defer server.Close()
            })
        }
    }
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题