Как обмануть метод http.Client Do
Я пытаюсь найти решение, чтобы написать тест и смоделировать HTTP-ответ. В моей функции, где я принимаю интерфейс:
type HttpClient interface {
Do(req *http.Request) (*http.Response, error)
}
Я делаю http получить запрос с базовой аутентификацией
func GetOverview(client HttpClient, overview *Overview) (*Overview, error) {
request, err := http.NewRequest("GET", fmt.Sprintf("%s:%s/api/overview", overview.Config.Url, overview.Config.Port), nil)
if (err != nil) {
log.Println(err)
}
request.SetBasicAuth(overview.Config.User, overview.Config.Password)
resp, err := client.Do(request)
Как я могу издеваться над этим HttpClient? Я ищу макет библиотеки, например: https://github.com/h2non/gock, но есть только макет для Get и Post
Может быть, я должен сделать это по-другому. Буду благодарен за совет
Ответы
Ответ 1
Любая структура с методом, соответствующим сигнатуре, которая у вас есть на вашем интерфейсе, будет реализовывать интерфейс. Например, вы можете создать struct ClientMock
type ClientMock struct {
}
с помощью метода
func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {
return &http.Response{}, nil
}
Затем вы можете вставить эту структуру ClientMock
в свой GetOverview
func. Здесь пример на игровой площадке Go.
Ответ 2
Пакет net/http/httptest
- ваш лучший друг:
// generate a test server so we can capture and inspect the request
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(scenario.expectedRespStatus)
res.Write([]byte("body"))
}))
defer func() { testServer.Close() }()
req, err := http.NewRequest(http.MethodGet, testServer.URL, nil)
assert.NoError(t, err)
res, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.Equal(t, scenario.expectedRespStatus, res.StatusCode, "status code should match the expected response")
Ответ 3
Я знаю, что было немного, но я только что написал что-то, чтобы помочь с этим в последнее время.
Обычно для издевательства HTTP-запросов я рекомендую запускать настоящий HTTP-сервер локально, поскольку в Go это легко сделать. https://golang.org/pkg/net/http/httptest/ - довольно стандартный способ сделать это (см. пример кода, заданного в типе сервера).
Однако, совершив много HTTP-издевательств, мне захотелось чего-то большего, как хорошая библиотека-макет: легкая настройка ожиданий, проверка того, что все запросы были сделаны, и т.д. Я обычно использовал https://godoc.org/github.com/stretchr/testify/mock для насмешек и желаемых функций.
Итак, я написал https://github.com/dankinder/httpmock, который в основном объединяет эти два.
Ответ 4
Вам нужно создать структуру с методами, соответствующими интерфейсу. Максы обычно используются для целей тестирования, поэтому люди хотят получить готовые возвращаемые значения макетных методов. Для этого мы создаем структуру с атрибутами func, соответствующими методам.
Как ваш интерфейс:
type HttpClient interface {
Do(req *http.Request) (*http.Response, error)
}
Эквивалентный макет:
type MockClient struct {
DoFunc func(req *http.Request) (*http.Response, error)
}
func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
if m.DoFunc != nil {
return m.DoFunc(req)
}
return &http.Response{}, nil
}
Затем, следующий шаг - написать несколько тестов. Пример здесь.
Ответ 5
Создайте фиктивный сервер из httpclient. Рабочий пример здесь:
https://github.com/mohammadiliyash/golang-mock-http-call