使用 Gorilla MUX 对 App Engine 进行单元测试
Unit Testing App Engine with Gorilla MUX
我想为 Google App Engine 中的处理程序编写测试,这些处理程序使用 Gorilla mux 从请求中读取变量 URL。
我从 documentation 了解到您可以创建一个虚假的上下文并请求用于测试。
我在测试中直接调用处理程序,但处理程序没有按预期看到路径参数。
func TestRouter(t *testing.T) {
inst, _ := aetest.NewInstance(nil) //ignoring error for brevity
defer inst.Close()
//tried adding this line because the test would not work with or without it
httptest.NewServer(makeRouter())
req, _ := inst.NewRequest("GET", "/user/john@example.com/id-123", nil)
req.Header.Add("X-Requested-With", "XMLHttpRequest")
resp := httptest.NewRecorder()
restHandler(resp, req)
}
func restHandler(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
params := mux.Vars(r)
email := params["email"]
//`email` is always empty
}
问题是处理程序总是看到一个空的 "email" 参数,因为 Gorilla mux 不解释该路径。
路由器如下:
func makeRouter() *mux.Router {
r := mux.Router()
rest := mux.NewRouter().Headers("Authorization", "").
PathPrefix("/api").Subrouter()
app := r.Headers("X-Requested-With", "XMLHttpRequest").Subrouter()
app.HandleFunc("/user/{email}/{id}", restHandler).Methods(http.MethodGet)
//using negroni for path prefix /api
r.PathPrefx("/api").Handler(negroni.New(
negroni.HandlerFunc(authCheck), //for access control
negroni.Wrap(rest),
))
return r
}
我的所有搜索都没有得到任何特定于使用 Gorilla mux 进行 App Engine 单元测试的信息。
由于您要测试的是处理程序,您可以只获取路由器的一个实例并在其上调用 ServeHTTP。这是它应该如何基于您的代码。
main.go
func init() {
r := makeRouter()
http.Handle("/", r)
}
func makeRouter() *mux.Router {
r := mux.NewRouter()
app := r.Headers("X-Requested-With", "XMLHttpRequest").Subrouter()
app.HandleFunc("/user/{email}/{id}", restHandler).Methods(http.MethodGet)
return r
}
func restHandler(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
email := params["email"]
fmt.Fprintf(w, email)
}
main_test.go
func TestRouter(t *testing.T) {
inst, _ := aetest.NewInstance(nil) //ignoring error for brevity
defer inst.Close()
req, _ := inst.NewRequest("GET", "/user/john@example.com/id-123", nil)
req.Header.Add("X-Requested-With", "XMLHttpRequest")
rec := httptest.NewRecorder()
r := makeRouter()
r.ServeHTTP(rec, req)
if email := rec.Body.String(); email != "john@example.com" {
t.Errorf("router failed, expected: %s, got: %s", "john@example.com", email)
}
}
请注意,我删除了 rest
路线,因为那不是您测试的一部分,但想法是一样的。也没有为简单起见检查错误。
我想为 Google App Engine 中的处理程序编写测试,这些处理程序使用 Gorilla mux 从请求中读取变量 URL。
我从 documentation 了解到您可以创建一个虚假的上下文并请求用于测试。
我在测试中直接调用处理程序,但处理程序没有按预期看到路径参数。
func TestRouter(t *testing.T) {
inst, _ := aetest.NewInstance(nil) //ignoring error for brevity
defer inst.Close()
//tried adding this line because the test would not work with or without it
httptest.NewServer(makeRouter())
req, _ := inst.NewRequest("GET", "/user/john@example.com/id-123", nil)
req.Header.Add("X-Requested-With", "XMLHttpRequest")
resp := httptest.NewRecorder()
restHandler(resp, req)
}
func restHandler(w http.ResponseWriter, r *http.Request) {
ctx := appengine.NewContext(r)
params := mux.Vars(r)
email := params["email"]
//`email` is always empty
}
问题是处理程序总是看到一个空的 "email" 参数,因为 Gorilla mux 不解释该路径。
路由器如下:
func makeRouter() *mux.Router {
r := mux.Router()
rest := mux.NewRouter().Headers("Authorization", "").
PathPrefix("/api").Subrouter()
app := r.Headers("X-Requested-With", "XMLHttpRequest").Subrouter()
app.HandleFunc("/user/{email}/{id}", restHandler).Methods(http.MethodGet)
//using negroni for path prefix /api
r.PathPrefx("/api").Handler(negroni.New(
negroni.HandlerFunc(authCheck), //for access control
negroni.Wrap(rest),
))
return r
}
我的所有搜索都没有得到任何特定于使用 Gorilla mux 进行 App Engine 单元测试的信息。
由于您要测试的是处理程序,您可以只获取路由器的一个实例并在其上调用 ServeHTTP。这是它应该如何基于您的代码。
main.go
func init() {
r := makeRouter()
http.Handle("/", r)
}
func makeRouter() *mux.Router {
r := mux.NewRouter()
app := r.Headers("X-Requested-With", "XMLHttpRequest").Subrouter()
app.HandleFunc("/user/{email}/{id}", restHandler).Methods(http.MethodGet)
return r
}
func restHandler(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
email := params["email"]
fmt.Fprintf(w, email)
}
main_test.go
func TestRouter(t *testing.T) {
inst, _ := aetest.NewInstance(nil) //ignoring error for brevity
defer inst.Close()
req, _ := inst.NewRequest("GET", "/user/john@example.com/id-123", nil)
req.Header.Add("X-Requested-With", "XMLHttpRequest")
rec := httptest.NewRecorder()
r := makeRouter()
r.ServeHTTP(rec, req)
if email := rec.Body.String(); email != "john@example.com" {
t.Errorf("router failed, expected: %s, got: %s", "john@example.com", email)
}
}
请注意,我删除了 rest
路线,因为那不是您测试的一部分,但想法是一样的。也没有为简单起见检查错误。