为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
函数式编程 2022-01-10 14:51:46
我有这个 net/http 服务器设置,链中有几个中间件,我找不到关于如何测试这些的示例......我在 gorilla/mux 路由器上使用基本的 net/http,一个 Handle 看起来有点像这样:r.Handle("/documents", addCors(checkAPIKey(getDocuments(sendJSON)))).Methods("GET")在这些中,我汇总了一些数据并通过 Gorilla Context context.Set 方法提供它们。通常我用httptest测试我的http函数,我也希望用这些来做,但我不知道怎么做,我很好奇什么是最好的方法。我应该单独测试每个中间件吗?我应该在需要时预先填充适当的上下文值吗?我可以一次测试整个链,以便我可以检查输入的所需状态吗?
查看完整描述

1 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

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


相反,单独测试您的中间件和处理程序 - 就像您可以控制的那样。


但是,如果您准备测试堆栈(mux -> 处理程序 -> 处理程序 -> 处理程序 -> MyHandler),那么使用函数作为变量全局定义中间件可能会有所帮助:


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 中测试的底层数据流的互斥状态),我建议在实际主 Handler 函数的上下文之外对中间件进行单元测试。


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


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信