由于某种原因,我似乎无法得到ioutil.ReadAll(res.Body)
,其中res
是*http.Response
返回的res, err := hc.Do(redirectRequest)
(对于hc http.Client
,{{1} }。
到目前为止的测试策略
任何时候我在SUT中看到redirectRequest *http.Request
或hc.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()
。
答案 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()