HTTP Unit Test
Now you have written a simple HTTP server with multiple endpoints. It is time to write unit tests for them. You may be wondering, isn't it troublesome to setup a test server to test a particular handler for a given endpoint? Well it turns out that you don't actually need a server to test handler logic.
httptest
httptestGolang has a built-in test package for http package related items. Recall that HTTP handler has the following declaration.
package http
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}When we write a function like the following
func FooHandler(w http.ResponseWriter, r *http.Request) {
// Logic...
}This is known as a Handlerfunc which is essentially an adapter to allow the use of ordinary function as HTTP handlers. It does so by attaching a ServeHTTP method to FooHandler.
http.HandlerFunc(FooHandler) // Casting
// Gain the following method automatically.
func (f FooHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
f(w, r)
}In order to test any handler, we only need to provide two inputs, i.e. a response writer and a request object. If we can somehow mock these two items, we can test any handler function. This is exactly what httptest package provides you.
Mocks
Let's first mock a response writer using *httptest.ResponseRecorder. The recorder records the response coming from a handler. Remember that handler uses w.Write to write bytes into HTTP responses. We want to record those bytes and see if the handler is behaving correctly. The recorder gives us a HTTP response which has the recorded bytes via recorder.Result().
The next item to mock is request. This one is also very straightforward, you simply ask the package to give you a request object. You can add headers, body, and query parameters to it, just like a regular request.
We are now ready to put everything together.
Last updated