Go
Beginner
1 min read
Testing HTTP Handlers with httptest
Example
package handler_test
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
type UserStore interface {
GetUser(id int) (string, bool)
}
type fakeStore struct {
users map[int]string
}
func (f *fakeStore) GetUser(id int) (string, bool) {
name, ok := f.users[id]
return name, ok
}
func userHandler(store UserStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id := 1 // simplified; real code uses r.PathValue
name, ok := store.GetUser(id)
if !ok {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"name": name})
}
}
func TestUserHandler(t *testing.T) {
store := &fakeStore{users: map[int]string{1: "Alice"}}
handler := userHandler(store)
// Unit-level: recorder test
req := httptest.NewRequest(http.MethodGet, "/users/1", nil)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Errorf("expected 200, got %d", rec.Code)
}
var body map[string]string
json.NewDecoder(rec.Body).Decode(&body)
if body["name"] != "Alice" {
t.Errorf("expected Alice, got %q", body["name"])
}
// Integration-level: real server
ts := httptest.NewServer(handler)
defer ts.Close()
resp, _ := http.Get(ts.URL + "/users/1")
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Errorf("server test: expected 200, got %d", resp.StatusCode)
}
}
Related Resources
This is the last lesson in this section.
Create a free account to earn a certificate