Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write unit test for http request in golang?

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\n", 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.

like image 407
Utkarsh Mani Tripathi Avatar asked Dec 18 '22 01:12

Utkarsh Mani Tripathi


1 Answers

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\n", 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()
        })
    }
}
like image 60
Iain Duncan Avatar answered Jan 05 '23 22:01

Iain Duncan