Как протестировать HTTP-обработчик в Go через httptest

Как протестировать HTTP-обработчик в Go через httptest
Содержание статьи

Для теста HTTP-обработчика Go создайте запрос через httptest.NewRequest() и запишите результат в httptest.NewRecorder(). Прямой вызов обработчика позволяет проверить ответ без сетевого порта. На Mentoring.digital разберём это на ручке готовности сервиса.

Вызовите обработчик с тестовым запросом

Поместите фрагмент в ready_test.go существующего Go-модуля. Если пакет называется иначе, замените его имя в первой строке.

package ready

import (
    "io"
    "net/http"
    "net/http/httptest"
    "testing"
)

func ready(w http.ResponseWriter, _ *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    w.WriteHeader(http.StatusOK)
    _, _ = io.WriteString(w, "ready\n")
}

func TestReady(t *testing.T) {
    req := httptest.NewRequest(http.MethodGet, "/ready", nil)
    recorder := httptest.NewRecorder()
    ready(recorder, req)

    resp := recorder.Result()
    defer resp.Body.Close()
    if resp.StatusCode != http.StatusOK {
        t.Fatalf("status = %d", resp.StatusCode)
    }
    if got := resp.Header.Get("Content-Type"); got != "text/plain" {
        t.Fatalf("Content-Type = %q", got)
    }
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        t.Fatal(err)
    }
    if string(body) != "ready\n" {
        t.Fatalf("body = %q", body)
    }
}

Result() вызывают после завершения обработчика. Сравнивайте нужные поля ответа, например статус и заголовок. В строке тела здесь важен и символ новой строки. Запустите go test из каталога пакета и попробуйте изменить ожидаемый текст, чтобы увидеть сообщение при несовпадении.

Добавьте проверку маршрута или клиента

Прямой вызов проверяет сам обработчик. Если важно, как приложение выбирает обработчик по пути, вызовите ServeHTTP настроенного маршрутизатора с тем же рекордером. Для проверки HTTP-клиента, редиректа или поведения на реальном локальном соединении подойдёт httptest.NewServer. Закройте тестовый сервер через defer server.Close().

Практику тестирования можно продолжить на индивидуальном курсе Go. Разделение тестов обработчика и клиента удобно обсудить с наставником по Go.

Похожие статьи по данной теме