testing - 我应该如何使用 gorilla 上下文对中间件包进行单元测试

标签 testing go

我有这个 net/http 服务器设置,链中有几个中间件,但我找不到关于如何测试这些中间件的示例...

我在 gorilla/mux 路由器上使用基本的 net/http,一个 Handle 看起来有点像这样:

r.Handle("/documents", addCors(checkAPIKey(getDocuments(sendJSON)))).Methods("GET")

在这些中,我聚合了一些数据并通过 Gorilla Context context.Set 方法提供它们。

通常我用 httptest 测试我的 http 函数,我也希望用它们来测试,但我不知道如何做,我很好奇什么是最好的方法。我应该单独测试每个中间件吗?我应该在需要时预填充适当的上下文值吗?我可以一次测试整个链,这样我就可以检查所需的输入状态吗?

最佳答案

我不会测试涉及 Gorilla 或任何其他第 3 方包的任何内容。如果您想测试以确保其正常工作,我会为您的应用程序的运行版本(例如 C.I. 服务器)的端点设置一些外部测试运行器或集成套件。

相反,单独测试您的中间件和处理程序 - 因为它们是您可以控制的。

但是,如果您打算测试堆栈 (mux -> handler -> handler -> handler -> MyHandler),那么使用 functions as vars 全局定义中间件可能会有所帮助:

var addCors = func(h http.Handler) http.Handler {
  ...
}

var checkAPIKey = func(h http.Handler) http.Handler {
  ...
}

在正常使用过程中,它们的实现保持不变。

r.Handle("/documents", addCors(checkAPIKey(getDocuments(sendJSON)))).Methods("GET")

但是对于单元测试,您可以覆盖它们:

// important to keep the same package name for
// your test file, so you can get to the private
// vars.
package main

import (
  "testing"
)

func TestXYZHandler(t *testing.T) {

  // save the state, so you can restore at the end
  addCorsBefore := addCors
  checkAPIKeyBefore := checkAPIKey

  // override with whatever customization you want
  addCors = func(h http.Handler) http.Handler {
    return h
  }
  checkAPIKey = func(h http.Handler) http.Handler {
    return h
  }

  // arrange, test, assert, etc.
  //

  // when done, be a good dev and restore the global state
  addCors = addCorsBefore
  checkAPIKey = checkAPIKeyBefore
}

如果您发现自己经常复制粘贴此样板代码,请将其移至单元测试中的全局模式:

package main

import (
  "testing"
)

var (
  addCorsBefore = addCors
  checkAPIKeyBefore = checkAPIKey
)

func clearMiddleware() {
  addCors = func(h http.Handler) http.Handler {
    return h
  }
  checkAPIKey = func(h http.Handler) http.Handler {
    return h
  }
}

func restoreMiddleware() {
  addCors = addCorsBefore
  checkAPIKey = checkAPIKeyBefore
}

func TestXYZHandler(t *testing.T) {

  clearMiddleware()

  // arrange, test, assert, etc.
  //

  restoreMiddleware()
}

关于单元测试端点的旁注...

由于中间件应该以合理的默认值运行(预期正常传递,而不是你想在 func 中测试的底层数据流的互斥状态),我建议在你的实际主处理程序函数的上下文之外对中间件进行单元测试.

这样,您就有了一组严格针对您的中间件的单元测试。另一组测试纯粹关注您正在调用的 url 的主要处理程序。它使新手更容易发现代码。

关于testing - 我应该如何使用 gorilla 上下文对中间件包进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37143935/

相关文章:

python - 如何测试 Django 模型方法 __str__()

git - 如何避免使用 `go get` 更新自己

go - 如何遍历 PostForm 中的数组值?

rest - 是否可以在内部(私有(private))IIS 服务器上运行 Golang REST Web 应用程序?

testing - 如何在 Haskell 中使用 SmallCheck?

c - 如何针对细微错误设计软件测试

swift - 测试 NSURLSession "resume cannot be sent to abstract instance of class NSURLSessionDataTask"

testing - Easy B 测试多个输入/输出值

go - 如何在 Visual Studio Code 中使用 Delve 调试器

go - 如何导入本地包?