How to Write Test for HTTP Handler in Go: Simple Guide
To write a test for an
http.Handler in Go, use the net/http/httptest package to create a test server or request recorder. Then, call your handler with a crafted http.Request and check the http.ResponseRecorder for expected status and body.Syntax
Use httptest.NewRecorder() to record the response your handler writes. Create a new http.Request with http.NewRequest() to simulate a client request. Call your handler's ServeHTTP method with these objects. Finally, check the recorder's Code and Body for expected results.
go
recorder := httptest.NewRecorder() request, _ := http.NewRequest("GET", "/path", nil) handler := http.HandlerFunc(yourHandlerFunction) handler.ServeHTTP(recorder, request) // Check recorder.Code and recorder.Body.String() for test assertions
Example
This example shows a simple HTTP handler that returns "Hello, world!" and a test that verifies the response status and body.
go
package main import ( "net/http" "net/http/httptest" "testing" ) func helloHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("Hello, world!")) } func TestHelloHandler(t *testing.T) { recorder := httptest.NewRecorder() req, err := http.NewRequest("GET", "/hello", nil) if err != nil { t.Fatal(err) } handler := http.HandlerFunc(helloHandler) handler.ServeHTTP(recorder, req) if status := recorder.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %%v want %%v", status, http.StatusOK) } expected := "Hello, world!" if recorder.Body.String() != expected { t.Errorf("handler returned unexpected body: got %%v want %%v", recorder.Body.String(), expected) } }
Common Pitfalls
- Not checking the error returned by
http.NewRequestcan hide setup problems. - Forgetting to use
httptest.NewRecorder()means you can't capture the handler's response. - Calling the handler incorrectly, such as not using
ServeHTTP, will not run the handler as expected. - Not verifying both status code and response body can miss bugs.
go
/* Wrong way: Not using httptest.NewRecorder */ // var w http.ResponseWriter // req, _ := http.NewRequest("GET", "/", nil) // handler := http.HandlerFunc(helloHandler) // handler.ServeHTTP(w, req) // w is nil, will panic /* Right way: Use httptest.NewRecorder */ recorder := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/", nil) handler := http.HandlerFunc(helloHandler) handler.ServeHTTP(recorder, req)
Quick Reference
Remember these key steps when testing HTTP handlers in Go:
- Create a
httptest.ResponseRecorderto capture output. - Build a test
http.Requestwith the desired method, URL, and body. - Call your handler's
ServeHTTPmethod with the recorder and request. - Check the recorder's
Codefor status andBodyfor response content.
Key Takeaways
Use httptest.NewRecorder to capture your handler's response in tests.
Create http.Request objects with http.NewRequest to simulate client calls.
Call your handler with ServeHTTP(recorder, request) to run the test.
Always check both the HTTP status code and response body for correctness.
Handle errors from http.NewRequest to avoid hidden test failures.