在Golang中使ioutil.ReadAll(response.Body)引发错误

时间:2018-10-18 16:42:34

标签: unit-testing go

由于某种原因,我似乎无法得到ioutil.ReadAll(res.Body),其中res*http.Response返回的res, err := hc.Do(redirectRequest)(对于hc http.Client,{{1} }。

到目前为止的测试策略

任何时候我在SUT中看到redirectRequest *http.Requesthc.Do,我的本能是启动一个假服务器,并为其指向适当的应用程序状态。在此测试中,这样的服务器如下所示:

http.Request

我似乎没有控制badServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // some stuff w.Write([some bad bytes]) })) defer badServer.Close() 的方法,这实际上是使我无法对所有功能进行100%测试完成的唯一方法。

我尝试在res.Body的处理函数中,将errorThrowingServer设置为存根r.Body,该存根会在调用io.ReadCloser时引发错误,但不会效果Read()

2 个答案:

答案 0 :(得分:1)

据我发现,所有工作部分的源文件都经过细读,在这里评论了使http.Response.Body.Read()失败的唯一方法:

https://golang.org/src/net/http/response.go#L53

  

在读取“正文”字段时,响应正文将按需流式传输。如果   网络连接失败或服务器终止响应,   Body.Read调用返回错误。

或者ioutil.ReadAll()中有可能在这里返回bytes.ErrTooLarge

https://golang.org/src/io/ioutil/ioutil.go#L20

  

如果缓冲区溢出,我们将获得bytes.ErrTooLarge。返回为   一个错误。还有其他恐慌情绪。

答案 1 :(得分:1)

您可以嘲弄身体。基本上body是一个io.ReadCloser接口,因此,您可以执行以下操作:

import (
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
)

type mockReadCloser struct {
    mock.Mock
}

func (m *mockReadCloser) Read(p []byte) (n int, err error) {
    args := m.Called(p)
    return args.Int(0), args.Error(1)
}

func (m *mockReadCloser) Close() error {
    args := m.Called()
    return args.Error(0)
}

func TestTestingSomethingWithBodyError(t *testing.T) {
    mockReadCloser := mockReadCloser{}
    // if Read is called, it will return error
    mockReadCloser.On("Read", mock.AnythingOfType("[]uint8")).Return(0, fmt.Errorf("error reading"))
    // if Close is called, it will return error
    mockReadCloser.On("Close").Return(fmt.Errorf("error closing"))

    request := &http.Request{
        // pass the mock address
        Body: &mockReadCloser,
    }

    expected := "what you expected"
    result := YourMethod(request)

    assert.Equal(t, expected, result)

    mockReadCloser.AssertExpectations(t)
}

要停止阅读,您可以使用:

mockReadCloser.On("Read", mock.AnythingOfType("[]uint8")).Return(0, io.EOF).Once()