h2non / gock

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽
https://pkg.go.dev/github.com/h2non/gock
MIT License
2.04k stars 106 forks source link

ioutil.ReadAll error testing. #75

Open ghost opened 3 years ago

ghost commented 3 years ago

I am trying to test the following line of code:

func ook() error {
        […]
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return errors.Wrap(err, "cannot read body, trying again")
    }

This is my test:


func (errReader) Read(p []byte) (int, error) {
    return 1, errors.New("Computer says NON!")
}

// Wait for vault to unseal: body error.
func TestWaitForVaultToUnsealBodyError(t *testing.T) {
    defer gock.Off() // Flush pending mocks after test execution

    gock.New(URL).
        Get("v1/seal-status").
        Reply(200).
        Body(errReader{})

        ook()
}

I removed the URL and other extra stuff, the code is a little (but not much) more complex than that. However, the ioutil.ReadAll refuses to spew an error. What am I doing wrong?

rafael-piovesan-hash commented 2 years ago

I've managed to test this using something as follows:

serverAPI := httptest.NewServer(
    http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                // says the response is longer than what we're actually returning
        w.Header().Add("Content-Length", "50")
                // return less bytes, wich will result in an "unexpected EOF" from ioutil.ReadAll()
        _, _ = w.Write([]byte("a"))
    }),
)
defer serverAPI.Close()
ibrt commented 2 years ago

Same issue here. The problem is that this library immediately consumes that response buffer and will have the mock RoundTripper return (nil, error) instead of (http.Response, nil) (with the reader as http.Response.Body).