Testing HTTP handlers in Go

nicolascb

Nicolas Barbosa

Posted on August 11, 2022

Testing HTTP handlers in Go

Introduction

In this example, I will create unit tests using the httptest library and we will see how to create test coverage for http handlers.

How to test http handlers in Go?

So we can test any handler http, we need a structure to be able to store the handler response, such as http status code, headers, body, etc.
The package httptest provide the structure httptest.ResponseRecorder, that's all we need to store the handler response.

// NewRecorder returns an initialized ResponseRecorder.
func NewRecorder() *ResponseRecorder {
    return &ResponseRecorder{
        HeaderMap: make(http.Header),
        Body:      new(bytes.Buffer),
        Code:      200,
    }
}
Enter fullscreen mode Exit fullscreen mode

The sample API

In our sample API, we have a handler called /check-is-prime, which checks if a number is prime.

The code:

The first test

The logic of the tests is very simple, for each test we build the HTTP request and then compare the response.

Adding more tests

Using table design in tests, its easy to add more cases:

{
    name: "must return http.StatusOk and true to prime number (7)",
    args: func(*testing.T) args {
        req, err := http.NewRequest("GET", "/check-is-prime", nil)
        if err != nil {
            t.Fatalf("fail to create request: %s", err.Error())
        }

        q := req.URL.Query()
        q.Add("number", "7")
        req.URL.RawQuery = q.Encode()

        return args{
            req: req,
        }
    },
    wantCode: http.StatusOK,
    wantBody: "true",
},
{
    name: "must return http.StatusOk and false because number (1) is not prime",
    args: func(*testing.T) args {
        req, err := http.NewRequest("GET", "/check-is-prime", nil)
        if err != nil {
            t.Fatalf("fail to create request: %s", err.Error())
        }

        q := req.URL.Query()
        q.Add("number", "1")
        req.URL.RawQuery = q.Encode()

        return args{
            req: req,
        }
    },
    wantCode: http.StatusOK,
    wantBody: "false",
},
Enter fullscreen mode Exit fullscreen mode

Complete code:

Conclusion

Have these utilities in the Go standard library, helps a lot when creating and maintaining our tests. We saw in practice with the package httptest.

Another important point is to isolate mux creation, this is necessary to call handlers in tests.

💖 💪 🙅 🚩
nicolascb
Nicolas Barbosa

Posted on August 11, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Example tests in Go
100daystooffload Example tests in Go

March 21, 2024

Go Test Doubles by Example
go Go Test Doubles by Example

January 2, 2024

Testing HTTP handlers in Go
go Testing HTTP handlers in Go

August 11, 2022