unit-testing - 使用 Gorilla MUX 对 App Engine 进行单元测试

标签 unit-testing google-app-engine go 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。以下是它应该如何基于您的代码。

ma​​in.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)
}

ma​​in_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 路由,因为那不是您测试的一部分,但想法是一样的。为简单起见,也没有检查错误。

关于unit-testing - 使用 Gorilla MUX 对 App Engine 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38456093/

相关文章:

c# - 使用 Moq 验证调用基类中的非虚拟方法

java - 如何使用java上传谷歌云存储中的文件

parsing - 如何使我的 go 解析器代码更具可读性

bash - 从带有空格的脚本导出环境变量

python - 如何覆盖时间戳字段以进行单元测试?

go - 较旧的服务传输较新版本的 Protocol Buffer 3 消息

c++ - 在 Visual Studio 中执行单个 Boost Test 单元测试

javascript - karma Jasmine 没有执行所有测试

c# - 手动将 RedirectToRouteResult 解析为查看结果

google-app-engine - Google Drive properties.insert 错误