Заставляя ioutil.ReadAll (response.Body) выдавать ошибку в golang - PullRequest
0 голосов
/ 18 октября 2018

По какой-то причине я не могу получить ioutil.ReadAll(res.Body), где res - это *http.Response, возвращаемое res, err := hc.Do(redirectRequest) (для hc http.Client, redirectRequest *http.Request).

Стратегия тестирования до настоящего времени

В любое время Я вижу hc.Do или http.Request в SUT, мой инстинкт состоит в том, чтобы раскрутитьфальшивый сервер и укажите ему соответствующие состояния приложений.Такой сервер для этого теста выглядит следующим образом:

badServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
    // some stuff
    w.Write([some bad bytes])
}))
defer badServer.Close()

Кажется, у меня нет способа контролировать res.Body, что в буквальном смысле единственное, что удерживает меня от 100% завершения теста противфункция, в которой все это.

Я пытался в функции обработчика errorThrowingServer установить r.Body на заглушку io.ReadCloser, которая выдает ошибку при вызове Read(), но это нене влияет res.

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Вы можете издеваться над телом.По сути, 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()
0 голосов
/ 18 октября 2018

Насколько я мог найти, просматривая исходные файлы для всех рабочих частей, единственный способ заставить http.Response.Body.Read() потерпеть неудачу, прокомментирован здесь:

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

Тело ответа передается по требованию при чтении поля Body.Если сетевое соединение не удается или сервер завершает ответ, вызовы Body.Read возвращают ошибку.

Или в ioutil.ReadAll() есть возможность вернуть bytes.ErrTooLarge здесь:

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

Если буфер переполнится, мы получим bytes.ErrTooLarge.Верните это как ошибку.Любая другая паника остается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...