liveBook · Manning

Httptest

As explained in 100 Go Mistakes and How to Avoid Them

httptest is a Go standard-library package that provides facilities for testing HTTP clients and servers.

A common mistake is starting a Docker-based mock server when a fast local test is enough. httptest supplies focused utilities for testing HTTP handlers and clients. section 11.7.1

Choose the test boundary deliberately:

  • Test a handler directly with httptest.NewRequest and httptest.NewRecorder. This calls the handler without testing the HTTP transport, then lets assertions inspect headers, body, and status. section 11.7.1
  • Test a client through httptest.NewServer. Supply a handler that returns a controlled response, pass srv.URL to the client, and close the server when finished. section 11.7.1
func TestHandler(t *testing.T) {
    req := httptest.NewRequest(http.MethodGet, "http://localhost",     #1
        strings.NewReader("foo"))
    w := httptest.NewRecorder()                                        #2
    Handler(w, req)                                                    #3
 
    if got := w.Result().Header.Get("X-API-VERSION"); got != "1.0" {   #4
        t.Errorf("api version: expected 1.0, got %s", got)
    }
 
    body, _ := ioutil.ReadAll(wordy)                                   #5
    if got := string(body); got != "hello foo" {
        t.Errorf("body: expected hello foo, got %s", got)
    }
 
    if http.StatusOK != w.Result().StatusCode {                        #6
        t.FailNow()
    }
}

Build a request, record the handler response, invoke the handler, and assert the resulting HTTP fields. section 11.7.1

Fast client test

A duration client can POST to a local httptest server whose handler returns {"duration": 314}; the test then verifies the parsed 314-second result without external infrastructure. section 11.7.1

func TestDurationClientGet(t *testing.T) {
    srv := httptest.NewServer(                                             #1
        http.HandlerFunc(
            func(w http.ResponseWriter, r *http.Request) {
                _, _ = w.Write([]byte(`{"duration": 314}`))                #2
            },
        ),
    )
    defer srv.Close()                                                      #3
 
    client := NewDurationClient()
    duration, err :=
        client.GetDuration(srv.URL, 51.551261, -0.1221146, 51.57, -0.13)   #4
    if err != nil {
        t.Fatal(err)
    }
 
    if duration != 314*time.Second {                                       #5
        t.Errorf("expected 314 seconds, got %v", duration)
    }
}

See the complete client test: create the server, defer Close, inject its URL, and assert the decoded duration. section 11.7.1

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains request construction, response recording, server lifecycle, assertions, and the boundary between handler and transport testing.
Examples
Uses a greeting handler, recorded headers and body, and a duration client receiving a 314-second JSON response.
What it assumes
Assumes familiarity with Go HTTP handlers, clients, requests, responses, and test assertions.
What you can do after
Apply it via Go's httptest package to test handlers or clients without Docker-based mock infrastructure.
How it connects
Connects HTTP handlers, HTTP clients, requests, responses, JSON parsing, and unit testing.

Also explained in

Compare how 4 books explain httptest →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.