1

i'm new to Golang and i'm trying to write a test for a simple HTTP client. i read a lot of ways of doing so also here in SO but none of them seems to work. I'm having troubles mocking the client response

This is how my client looks right now:

type API struct {
    Client  *http.Client
}

func (api *API) MyClient(qp string) ([]byte, error) {
    url := fmt.Sprintf("http://localhost:8000/myapi?qp=%s", qp)
    resp, err := api.Client.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    // handling error and doing stuff with body that needs to be unit tested
    if err != nil {
        return nil, err
    }
    return body, err
}

And this is my test function:

func TestDoStuffWithTestServer(t *testing.T) {
    // Start a local HTTP server
    server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        rw.Write([]byte(`OK`))
    }))
    defer server.Close()

    // Use Client & URL from our local test server
    api := API{server.Client()}
    body, _ := api.MyClient("1d")



    fmt.Println(body)

}    

As i said, this is how they look right cause i try lot of ways on doing so.

My problem is that i'm not able to mock the client respose. in this example my body is empty. my understanding was that rw.Write([]byte(OK)) should mock the response 🤔

2
  • @Volker that's why i'm asking the right way of testing this... as i said i'm new to Go so maybe instead of blaming me and downvoting the quesiton you could give me a better answer on how i could do this in the right way :) and anyway, if you take a look at the code, i do start a new httptest server... don't read only the title... cheers Commented Mar 21, 2022 at 9:34
  • What is the test supposed to check? I don't see any assertion... Commented Mar 21, 2022 at 12:03

1 Answer 1

2

In the end i solved it like this:

myclient:

type API struct {
    Endpoint string
}

func (api *API) MyClient(slot string) ([]byte, error) {
    url := fmt.Sprintf("%s/myresource?qp=%s", api.Endpoint, slot)
    c := http.Client{}
    resp, err := c.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    return body, err
}

test:

func TestDoStuffWithTestServer(t *testing.T) {
    server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
        rw.Write([]byte(`{Result: [{Cluster_name: "cl1", Pings: 2}]}`))
    }))

    defer server.Close()

    api := API{Endpoint: server.URL}
    res, _ := api.MyClient("1d")

    expected := []byte(`{Result: [{Cluster_name: "cl1", Pings: 2}]}`)

    if !bytes.Equal(expected, res) {
        t.Errorf("%s != %s", string(res), string(expected))
    }
}

still, not 100% sure is the right way of doing so in Go

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.