Muaaz Saleem
Posted on January 17, 2021
httptest.NewServer
gives us the ability to spin up a local HTTP Server. This is very useful say, when testing an HTTP client.
Usage
Here's a very basic usage of httptest.NewServer
:
server := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, req *http.Request) {
_, _ = fmt.Fprint(w, "OK")
}))
defer server.Close()
In the code above, server.URL
can be used to connect to the server. For example, we could pass it to the following pingService
func to test it.
func pingService(url string) ServiceStatus {
// TODO: make sure url is actually a valid URL
res, err := http.Get(url)
// expecting the HTTP client to err out if the service is down
if err != nil {
// TODO: add TestURL to the log
log.Errorf("[%s], is DOWN", url)
return ServiceDown
}
}
A more complete example
Following is a more complete example of pingService
and its tests:
pingService()
// ServiceStatus indicates the status of a service i.e "UP", "FAILING", "DOWN"
type ServiceStatus string
const (
ServiceUP = ServiceStatus("UP")
ServiceDown = ServiceStatus("DOWN")
ServiceFailing = ServiceStatus("FAILING")
)
func pingService(server *http.Server) ServiceStatus {
// TODO: make sure server.URL is actually a valid URL
res, err := http.Get(server.URL)
// expecting the HTTP client to err out if the service is down
if err != nil {
// TODO: add TestURL to the log
log.Errorf("[%s], is DOWN", server.URL)
return ServiceDown
}
if res.StatusCode >= 200 && res.StatusCode <= 500 {
log.Infof("[%s], is UP", server.URL)
return ServiceUP
} else {
log.Errorf("[%s], is FAILING", server.URL)
return ServiceFailing
}
}
Testing pingService()
// TestStatusDown tests pinging a non running HTTP service
func TestStatusDown(t *testing.T) {
ss := pingService(exampleTestService)
require.Equal(t, ServiceDown, ss)
}
// TestStatusUP tests a running HTTP service
func TestStatusUP(t *testing.T) {
sv := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, req *http.Request) {
_, _ = fmt.Fprint(w, "OK")
}))
defer sv.Close()
ss := pingService(sv)
require.Equal(t, ServiceUP, ss)
}
// TestStatusFailing tests a failing HTTP service
func TestStatusFailing(t *testing.T) {
sv := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer sv.Close()
ss := pingService(sv)
require.Equal(t, ServiceFailing, ss)
}
Further Resources:
💖 💪 🙅 🚩
Muaaz Saleem
Posted on January 17, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.