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.Requestwithhttptest.NewRequest. - Using
httptest.NewServerwhen 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
| Function | Description |
|---|---|
| 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.Body | Contains 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.