0

我想为 Google App Engine 中的处理程序编写测试,这些处理程序使用 Gorilla mux 从请求 URL 读取变量。

我从文档中了解到,您可以创建一个虚假的上下文并请求与测试一起使用。

我在测试中直接调用处理程序,但处理程序没有按预期看到路径参数。

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
}

问题是处理程序总是看到一个空的“电子邮件”参数,因为 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 单元测试的内容。

4

1 回答 1

0

由于您要测试的是处理程序,因此您可以获取路由器的一个实例并在其上调用 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路线,因为那不是您的测试的一部分,但想法是一样的。为简单起见,也没有检查错误。

于 2016-10-14T19:41:54.930 回答