0
0
GoHow-ToBeginner · 4 min read

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.NewRequest can 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.ResponseRecorder to capture output.
  • Build a test http.Request with the desired method, URL, and body.
  • Call your handler's ServeHTTP method with the recorder and request.
  • Check the recorder's Code for status and Body for 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.