In most of the docs I have seen, gorilla mux is suggested to be used like so...
func main() {
m := mux.Router()
m.HandleFunc("/", FuncNameOrDef)
http.ListenAndServe(":8080", m)
}
which is great, but it leaves me with a problem, because then in order to test, as far as I can see, I need to redeclare mux and routes unless I declare mux and routes outside of a function like this...
var (
m = mux.Router()
_ = m.HandleFunc("/", FuncNameOrDef)
)
and then in my tests do this...
func TestSomeView(t *testing.T) {
ts := httptest.NewServer(m)
....testing blah
}
which solves the problem, but then it makes the package pretty ugly (with all the _ = m.HandleFunc
's) Is there a more idiomatic way to do this?
You could use a factory function to create a new http.Handler
for you application. This would allow you to programmatically define the handlers and reuse them in the tests.
// NewApplicationHandler provides a configured handler for the
// application.
func NewApplicationHandler() http.Handler {
mux := mux.NewRouter()
mux.HandleFunc("/", handler)
return mux
}
func handler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World!"))
}
This example would be utilized in a test like so:
func TestApplicationServeMux(t *testing.T) {
// The handlers are being obtained via a call to the factory function.
applicationHandler := NewApplicationHandler()
ts := httptest.NewServer(applicationHandler)
defer ts.Close()
res, err := http.Get(ts.URL)
if err != nil {
t.Fatalf("%s", err)
}
defer res.Body.Close()
greeting, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatalf("%s", err)
}
want := []byte("Hello World!")
if !bytes.Equal(want, greeting) {
t.Errorf("Expected greeting %s; got %s", want, greeting)
}
}