0
0
GoHow-ToBeginner · 4 min read

How to Use httptest Package in Go for HTTP Testing

The httptest package in Go helps you create test HTTP servers and record HTTP requests and responses for testing your web handlers. You use httptest.NewServer to start a test server or httptest.NewRecorder to capture handler output without a real server.
📐

Syntax

The httptest package provides tools to test HTTP servers and handlers. Key functions include:

  • httptest.NewServer(handler http.Handler): Starts a real HTTP server for testing.
  • httptest.NewRecorder(): Creates a fake response writer to record handler output.

You pass your HTTP handler to these functions to simulate requests and check responses.

go
package main

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

// Start a test server
func startTestServer(handler http.Handler) *httptest.Server {
	return httptest.NewServer(handler)
}

// Create a response recorder
func createRecorder() *httptest.ResponseRecorder {
	return httptest.NewRecorder()
}
💻

Example

This example shows how to test a simple HTTP handler using httptest.NewRecorder to capture the response and check the status code and body.

go
package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
)

// helloHandler writes "Hello, world!" to the response
func helloHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Hello, world!"))
}

func main() {
	req := httptest.NewRequest("GET", "http://example.com/hello", nil)
	w := httptest.NewRecorder()

	helloHandler(w, req)

	resp := w.Result()
	body := w.Body.String()

	fmt.Println("Status Code:", resp.StatusCode)
	fmt.Println("Body:", body)
}
Output
Status Code: 200 Body: Hello, world!
⚠️

Common Pitfalls

Common mistakes when using httptest include:

  • Not calling w.Result() before reading the response.
  • Forgetting to create a proper http.Request with httptest.NewRequest.
  • Using httptest.NewServer when you only need to test a handler without a real server.

Always use httptest.NewRequest to create requests and httptest.NewRecorder to capture responses for handler tests.

go
package main

import (
	"net/http"
	"net/http/httptest"
	"fmt"
)

func handler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("OK"))
}

func main() {
	// Wrong: Using nil request
	// w := httptest.NewRecorder()
	// handler(w, nil) // This will panic

	// Right way:
	req := httptest.NewRequest("GET", "/", nil)
	w := httptest.NewRecorder()
	handler(w, req)

	resp := w.Result()
	fmt.Println("Status code:", resp.StatusCode)
}
Output
Status code: 200
📊

Quick Reference

FunctionDescription
httptest.NewServer(handler http.Handler)Starts a real HTTP server for integration testing.
httptest.NewRecorder()Creates a fake ResponseWriter to record handler output.
httptest.NewRequest(method, url string, body io.Reader)Creates a new HTTP request for testing handlers.
ResponseRecorder.Result()Returns the recorded HTTP response.
ResponseRecorder.BodyContains the response body as bytes.Buffer.

Key Takeaways

Use httptest.NewRequest and httptest.NewRecorder to test HTTP handlers without a real server.
httptest.NewServer starts a real HTTP server useful for integration tests.
Always call ResponseRecorder.Result() before reading the response status or body.
Avoid passing nil requests to handlers; always create requests with httptest.NewRequest.
Use httptest to simulate HTTP requests and verify responses easily in Go tests.