我在网络应用中使用gorilla / context。文档中的示例如下所示:
func MyHandler(w http.ResponseWriter, r *http.Request) {
//...
val := context.Get(r, foo.MyKey)
//...
}
如何对像这样工作的处理程序进行单元测试?我到目前为止管理的唯一方法是在我的测试中使用上下文包。我现在想,我可以将一个上下文参数注入到处理程序中,但后来我不符合HandlerFunc接口。
答案 0 :(得分:1)
这是一个经典的cross-cutting concerns示例。
您正在使用第三方神奇地处理被测单位的输入参数。根据这个定义,您将不得不做一些额外的设置,为您想要的状态准备context
。
当谈到Go http处理程序(其惯例是KISS)时,你不应该“超出上下文”#34;你的func获取额外的数据:在你的单个函数中保存你需要的所有数据。
就个人而言,我尽量避免像这样破坏我的处理程序。我想我曾经在我建造的几十个大型网站中使用了大猩猩的背景。这基本上是为了绕过缓存的响应,只是为了将数据保持为最终用户。其中我在单元测试中忽略了这一点,因为它不符合我测试的内容。
相反,我使用中间件包装器在我的句柄中设置我想要的基础知识并相应地修改处理程序的签名。
...等。我会创建一个中间件,当你用mux
注册它时使用大猩猩/上下文来查找你的cookie或用户名或者其他东西来包装你的处理程序,从缓存,数据库,redis等中隐藏那个用户对象,然后调用具有以下签名的处理程序:
func MyHandler(u User, p Page, w http.ResponseWriter, r *http.Request) {
// u is the User object loaded from middle-ware
// p is your global Page object... etc
}
这样,您的单元测试只会注入您需要测试的项目。
您可以在QA服务器上集成测试中间件与数据存储中的预期用户和页面对象。
答案 1 :(得分:1)
我的团队的方式是为路由处理程序添加一个名称,然后在测试中我们按名称调用该路由。
这是添加路线的方法:
r.HandleFunc("/<route>", MyHandler).Methods("GET").Name("MyHandlerByName")
然后就是如何测试它
r.Get("MyHandlerByName")
答案 2 :(得分:1)
测试句柄的一种方法是修改它们的创建方式。例如,创建一个返回http.HandlerFunc的函数,这个函数可以有参数。您可以模拟发送给函数的值
没有参数
session_start();
带参数
func State() http.HandlerFunc {
return http.HandlerFunc(func(pResponse http.ResponseWriter, r *http.Request) {
// your code
})
}
映射将是
func State(pParam1,pParam2,pParam3 ...) http.HandlerFunc {
return http.HandlerFunc(func(pResponse http.ResponseWriter, r *http.Request) {
// your code using pParam1,pParam2,pParam3
})
}
或
http.HandleFunc("/State", State())