I use gotests, and gorilla mux and I can unit test my http handlefunc handlers, but they do not respond to the proper http request methods as they should under the gorilla mux. How I can do a "live server" version of the test?
func main() {
router := mux.NewRouter()
router.HandleFunc("/", views.Index).Methods("GET")
}
func Index(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "INDEX\n")
}
func TestIndex(t *testing.T) {
req, _ := http.NewRequest("GET", "/", nil)
req1, _ := http.NewRequest("POST", "/", nil)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(Index)
type args struct {
w http.ResponseWriter
r *http.Request
}
tests := []struct {
name string
args args
}{
{name: "1: testing get", args: args{w: rr, r: req}},
{name: "2: testing post", args: args{w: rr, r: req1}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
handler.ServeHTTP(tt.args.w, tt.args.r)
log.Println(tt.args.w)
})
}
}
The problem here is that the function responds to both the get and post requests and doens't take into account my main router. This is fine for unit testing the function, but I think it would be better to just write an integrated test that tests the whole thing and gets everything out of the way in one go.
Use the net/http/httptest.Server type to test with a live server.
func TestIndex(t *testing.T) {
// Create server using the a router initialized elsewhere. The router
// can be a Gorilla mux as in the question, a net/http ServeMux,
// http.DefaultServeMux or any value that statisfies the net/http
// Handler interface.
ts := httptest.NewServer(router)
defer ts.Close()
newreq := func(method, url string, body io.Reader) *http.Request {
r, err := http.NewRequest(method, url, body)
if err != nil {
t.Fatal(err)
}
return r
}
tests := []struct {
name string
r *http.Request
}{
{name: "1: testing get", r: newreq("GET", ts.URL+"/", nil)},
{name: "2: testing post", r: newreq("POST", ts.URL+"/", nil)}, // reader argument required for POST
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resp, err := http.DefaultClient.Do(tt.r)
defer resp.Body.Close()
if err != nil {
t.Fatal(err)
}
// check for expected response here.
})
}
}
Although the question uses Gorilla mux, the approach and details in this answer apply to any router that satisfies the http.Handler interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With