Пакет httptest
Обзор
Пакет httptest предоставляет утилиты для тестирования HTTP.
Указатель
Файлы пакета
httptest.go recorder.go server.go
Константы
DefaultRemoteAddr — адрес удалённого узла, возвращаемый методом RemoteAddr по умолчанию, если для ResponseRecorder явно не задан DefaultRemoteAddr.
const DefaultRemoteAddr = "1.2.3.4"
func NewRequest 1.7
func NewRequest(method, target string, body io.Reader) *http.Request
NewRequest вызывает NewRequestWithContext, передавая ему context.Background.
func NewRequestWithContext 1.23
func NewRequestWithContext(ctx context.Context, method, target string, body io.Reader) *http.Request
NewRequestWithContext возвращает новый входящий запрос сервера Request, подходящий для передачи в http.Handler при тестировании.
target — это «request-target» из RFC 7230: он может быть путём или абсолютным URL. Если target — абсолютный URL, используется имя хоста из URL. В противном случае используется "example.com".
Если схема target — "https", полю TLS присваивается ненулевое фиктивное значение.
Значение Request.Proto всегда равно HTTP/1.1.
Пустой метод означает "GET".
Переданное тело может быть nil. Если тело имеет тип bytes.Reader, strings.Reader, bytes.Buffer или является значением http.NoBody, задаётся значение Request.ContentLength.
В случае ошибки NewRequest вызывает панику, что упрощает использование в тестах, где паника допустима.
Чтобы создать HTTP-запрос клиента, а не запрос сервера, см. функцию NewRequest в пакете net/http.
type ResponseRecorder
ResponseRecorder — это реализация http.ResponseWriter, которая записывает изменения для последующего анализа в тестах.
type ResponseRecorder struct {
// Code is the HTTP response code set by WriteHeader.
//
// Note that if a Handler never calls WriteHeader or Write,
// this might end up being 0, rather than the implicit
// http.StatusOK. To get the implicit value, use the Result
// method.
Code int
// HeaderMap contains the headers explicitly set by the Handler.
// It is an internal detail.
//
// Deprecated: HeaderMap exists for historical compatibility
// and should not be used. To access the headers returned by a handler,
// use the Response.Header map as returned by the Result method.
HeaderMap http.Header
// Body is the buffer to which the Handler's Write calls are sent.
// If nil, the Writes are silently discarded.
Body *bytes.Buffer
// Flushed is whether the Handler called Flush.
Flushed bool
// contains filtered or unexported fields
}
Пример
Код:
handler := func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "<html><body>Hello World!</body></html>")
}
req := httptest.NewRequest("GET", "http://example.com/foo", nil)
w := httptest.NewRecorder()
handler(w, req)
resp := w.Result()
body, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode)
fmt.Println(resp.Header.Get("Content-Type"))
fmt.Println(string(body))
Вывод:
200 text/html; charset=utf-8 <html><body>Hello World!</body></html>
func NewRecorder
func NewRecorder() *ResponseRecorder
NewRecorder возвращает инициализированный ResponseRecorder.
func (*ResponseRecorder) Flush
func (rw *ResponseRecorder) Flush()
Flush реализует http.Flusher. Чтобы проверить, был ли вызван Flush, см. rw.Flushed.
func (*ResponseRecorder) Header
func (rw *ResponseRecorder) Header() http.Header
Header реализует http.ResponseWriter. Он возвращает заголовки ответа, которые можно изменить в обработчике. Чтобы проверить заголовки, записанные после завершения обработчика, используйте метод ResponseRecorder.Result и обратитесь к полю Header возвращённого значения Response.
func (*ResponseRecorder) Result 1.7
func (rw *ResponseRecorder) Result() *http.Response
Result возвращает ответ, сформированный обработчиком.
Возвращённый Response будет содержать как минимум поля StatusCode, Header, Body и, возможно, Trailer. В будущем могут быть заполнены и другие поля, поэтому вызывающему коду не следует сравнивать результат с помощью DeepEqual в тестах.
Response.Header представляет собой снимок заголовков на момент первого вызова записи или на момент этого вызова, если обработчик не выполнял запись.
Гарантируется, что Response.Body не равен nil, а вызов Body.Read не вернёт ошибок, кроме io.EOF.
Result следует вызывать только после завершения работы обработчика.
func (*ResponseRecorder) Write
func (rw *ResponseRecorder) Write(buf []byte) (int, error)
Write реализует http.ResponseWriter. Данные из buf записываются в rw.Body, если он не равен nil.
func (*ResponseRecorder) WriteHeader
func (rw *ResponseRecorder) WriteHeader(code int)
WriteHeader реализует http.ResponseWriter.
func (*ResponseRecorder) WriteString 1.6
func (rw *ResponseRecorder) WriteString(str string) (int, error)
WriteString реализует io.StringWriter. Данные из str записываются в rw.Body, если он не равен nil.
type Server
Server — это HTTP-сервер для сквозного тестирования HTTP.
Для большинства тестов следует создавать сервер с помощью NewTestServer. Метод Server.Client возвращает клиент, который отправляет запросы тестовому серверу.
// Create a test server and send a request to it.
server := httptest.NewTestServer(t, handler)
resp, err := server.Client().Get("http://www.example.com/")
Настройка
Перед использованием тесты могут изменить настройки Server. После первого вызова Server.Client, Server.Start или Server.StartTLS настройки менять нельзя.
// Configure a test server before using.
server := httptest.NewTestServer(t, handler)
server.Config.MaxHeaderBytes = 1024
resp, err := server.Client().Get("http://www.example.com/")
Тесты
Серверы, созданные с помощью NewTestServer:
- Завершают тест с ошибкой, если обработчик сервера вызывает панику со значением, отличным от http.ErrAbortHandler.
- Регистрируют функцию Cleanup для остановки сервера в конце теста.
Серверы, созданные любым другим способом, необходимо останавливать вручную с помощью Server.Close.
Сеть в памяти
Сервер может использовать реализацию сети в памяти или прослушивать локальный сетевой интерфейс loopback. В большинстве тестов следует использовать сеть в памяти: она позволяет избежать исчерпания портов и других временных проблем с сетью и подходит для использования с пакетом testing/synctest.
Чтобы использовать сеть в памяти, создайте сервер с помощью NewTestServer. Не вызывайте Server.Start или Server.StartTLS.
При использовании сети в памяти объект http.Client, возвращённый методом Server.Client, настраивается для отправки всех запросов серверу. Клиент будет направлять серверу HTTP- и HTTPS-запросы независимо от адреса назначения или имени хоста. В качестве базового URL запросов не обязательно использовать Server.URL.
server := httptest.NewTestServer(t, handler)
client := server.Client()
// All of these requests are sent to the test server.
// https:// requests use TLS over the in-memory network.
_, _ = client.Get("http://www.example.com/")
_, _ = client.Get("https://go.dev/")
_, _ = client.Get("http://10.0.0.1/")
При использовании сети в памяти поле Server.Listener не задаётся.
Сеть loopback
Чтобы прослушивать интерфейс loopback, вызовите Server.Start или Server.StartTLS. Сервер будет прослушивать порт, выбранный системой.
Серверы loopback обслуживают запросы по HTTP (если запущены с помощью Server.Start) или HTTPS (если запущены с помощью Server.StartTLS).
При использовании сети loopback объект http.Client, возвращённый методом Server.Client, настраивается для отправки серверу запросов с именем хоста "example.com" или поддоменом ".example.com".
Запросы также можно отправлять на loopback-адрес сервера. Поле Server.URL содержит базовый URL с адресом сервера.
server := httptest.NewTestServer(t, handler) server.Start() client := server.Client() // This request is sent to the test server. _, _ = server.Client().Get(server.URL + "/") // This request (using http.DefaultClient) is also sent to the test server, // since server.URL contains the server's local IP address. _, _ = http.Get(server.URL + "/")
type Server struct {
// URL is the base URL of the server, of the form http://address:port
// with no trailing slash.
//
// It is set by the first call to Client, Start, or StartTLS.
//
// For servers listening on loopback, the address is the loopback IP address
// of the server.
//
// For servers using the in-memory network, this address is "example.com".
// Requests sent to servers using the in-memory network may use any address.
// It is not necessary to use this base URL.
URL string
// Listener is the network listener for servers listening on loopback.
// It is not set for servers using the in-memory network.
Listener net.Listener
// EnableHTTP2 controls whether HTTP/2 is enabled on the server.
// It must be set before calling Client, Start, or StartTLS.
EnableHTTP2 bool // Go 1.14
// TLS is the optional TLS configuration, populated with a new config
// after TLS is started. If set on an unstarted server before StartTLS
// is called, existing fields are copied into the new config.
TLS *tls.Config
// Config may be changed before calling Client, Start, or StartTLS.
Config *http.Server
// contains filtered or unexported fields
}
Пример
Код:
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
}))
defer ts.Close()
res, err := http.Get(ts.URL)
if err != nil {
log.Fatal(err)
}
greeting, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", greeting)
Вывод:
Hello, client
Пример (HTTP2)
Код:
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s", r.Proto)
}))
ts.EnableHTTP2 = true
ts.StartTLS()
defer ts.Close()
res, err := ts.Client().Get(ts.URL)
if err != nil {
log.Fatal(err)
}
greeting, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", greeting)
Вывод:
Hello, HTTP/2.0
func NewServer
func NewServer(handler http.Handler) *Server
NewServer запускает и возвращает новый Server, прослушивающий локальный сетевой интерфейс loopback. Эквивалентно вызову NewUnstartedServer, за которым следует Server.Start.
После завершения работы вызывающий код должен вызвать Server.Close, чтобы остановить сервер.
Большинству пользователей вместо этого следует использовать NewTestServer. Подробности см. в документации Server.
func NewTLSServer
func NewTLSServer(handler http.Handler) *Server
NewTLSServer запускает и возвращает новый Server, использующий TLS и прослушивающий локальный сетевой интерфейс loopback. Эквивалентно вызову NewUnstartedServer, за которым следует Server.StartTLS.
После завершения работы вызывающий код должен вызвать Server.Close, чтобы остановить сервер.
Большинству пользователей вместо этого следует использовать NewTestServer. Подробности см. в документации Server.
Пример
Код:
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
}))
defer ts.Close()
client := ts.Client()
res, err := client.Get(ts.URL)
if err != nil {
log.Fatal(err)
}
greeting, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", greeting)
Вывод:
Hello, client
func NewTestServer 1.27
func NewTestServer(t testing.TB, handler http.Handler) *Server
NewTestServer возвращает новый Server для теста. По умолчанию сервер использует реализацию сети в памяти.
Если handler равен nil, сервер будет возвращать ответ 500 на все запросы. Он не будет использовать http.DefaultServeMux.
Дополнительные сведения см. в документации Server.
func NewUnstartedServer
func NewUnstartedServer(handler http.Handler) *Server
NewUnstartedServer возвращает новый Server, прослушивающий локальный сетевой интерфейс loopback. Сервер не запускается.
После изменения настроек сервера вызывающий код должен вызвать Server.Start или Server.StartTLS.
После завершения работы вызывающий код должен вызвать Server.Close, чтобы остановить сервер.
Большинству пользователей вместо этого следует использовать NewTestServer. Подробности см. в документации Server.
func (*Server) Certificate 1.9
func (s *Server) Certificate() *x509.Certificate
Certificate возвращает сертификат, используемый сервером, или nil, если сервер не использует TLS.
func (*Server) Client 1.9
func (s *Server) Client() *http.Client
Client возвращает HTTP-клиент, настроенный для отправки запросов серверу. Он настроен доверять тестовому TLS-сертификату сервера и закрывает простаивающие соединения при вызове Server.Close.
func (*Server) Close
func (s *Server) Close()
Close останавливает сервер и блокирует выполнение, пока не завершатся все выполняющиеся запросы к этому серверу.
func (*Server) CloseClientConnections
func (s *Server) CloseClientConnections()
CloseClientConnections закрывает все открытые HTTP-соединения с тестовым сервером Server.
func (*Server) Start
func (s *Server) Start()
Start запускает сервер на локальном сетевом интерфейсе loopback.
Сервер должен быть создан с помощью NewTestServer или NewUnstartedServer.
func (*Server) StartTLS
func (s *Server) StartTLS()
Start запускает TLS на сервере, работающем на локальном сетевом интерфейсе loopback.
Сервер должен быть создан с помощью NewTestServer или NewUnstartedServer.
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/net/http/httptest/