在 Golang 中测试 HTTP 路由

Posted

技术标签:

【中文标题】在 Golang 中测试 HTTP 路由【英文标题】:Testing HTTP routes in Golang 【发布时间】:2014-10-09 19:42:30 【问题描述】:

我正在使用 Gorilla mux 和 net/http 包创建一些路由,如下所示

package routes

//some imports

//some stuff

func AddQuestionRoutes(r *mux.Router) 
    s := r.PathPrefix("/questions").Subrouter()
    s.HandleFunc("/question_id/question_type", getQuestion).Methods("GET")
    s.HandleFunc("/", postQuestion).Methods("POST")
    s.HandleFunc("/", putQuestion).Methods("PUT")
    s.HandleFunc("/question_id", deleteQuestion).Methods("DELETE")

我正在尝试编写一个测试来测试这些路线。例如,我正在尝试测试 GET 路由,专门尝试返回 400,所以我有以下测试代码。

package routes

//some imports

var m *mux.Router
var req *http.Request
var err error
var respRec *httptest.ResponseRecorder

func init() 
    //mux router with added question routes
    m = mux.NewRouter()
    AddQuestionRoutes(m)

    //The response recorder used to record HTTP responses
    respRec = httptest.NewRecorder()


func TestGet400(t *testing.T) 
    //Testing get of non existent question type
    req, err = http.NewRequest("GET", "/questions/1/SC", nil)
    if err != nil 
        t.Fatal("Creating 'GET /questions/1/SC' request failed!")
    

    m.ServeHTTP(respRec, req)

    if respRec.Code != http.StatusBadRequest 
        t.Fatal("Server error: Returned ", respRec.Code, " instead of ", http.StatusBadRequest)
    

但是,当我运行这个测试时,我得到一个 404 可能是因为请求没有被正确路由。?

当我从浏览器测试这条 GET 路由时,它确实返回了 400,所以我确定测试的设置方式存在问题。

【问题讨论】:

没有看到getQuestion的代码很难说。我已经重新创建了您的设置并将getQuestion 实现为无操作。当我运行go test ./... 时,出现以下故障:routes_test.go:32: Server error: Returned 200 instead of 400 想通了。我实际上正在运行其他测试,但我使用的是相同的respRec,而不是使用httptest.NewRecorder() 制作新的记录器。我想重复使用相同的 httpRecorder 有一些限制。 【参考方案1】:

这里使用 init() 是值得怀疑的。它仅作为程序初始化的一部分执行一次。相反,也许是这样的:

func setup() 
    //mux router with added question routes
    m = mux.NewRouter()
    AddQuestionRoutes(m)

    //The response recorder used to record HTTP responses
    respRec = httptest.NewRecorder()


func TestGet400(t *testing.T) 
    setup()
    //Testing get of non existent question type
    req, err = http.NewRequest("GET", "/questions/1/SC", nil)
    if err != nil 
        t.Fatal("Creating 'GET /questions/1/SC' request failed!")
    

    m.ServeHTTP(respRec, req)

    if respRec.Code != http.StatusBadRequest 
        t.Fatal("Server error: Returned ", respRec.Code, " instead of ", http.StatusBadRequest)
    

在每个适当的测试用例开始时调用 setup() 的地方。您的原始代码与其他测试共享相同的 respRec,这可能会污染您的测试结果。

如果您需要一个提供更多功能(如 setup/teardown 固定装置)的测试框架,请参阅 gocheck 等软件包。

【讨论】:

能否请您显示 AddQuestionRoutes(),我们可以只添加测试特定路线吗? 抱歉,知道了,问题本身

以上是关于在 Golang 中测试 HTTP 路由的主要内容,如果未能解决你的问题,请参考以下文章

Golang-鏌ユ壘(浜屽垎娉曟煡鎵?

GRPC使用错误排查记录

Golang 分割字符串

golang httprouter

如何在 golang 中将直方图添加到 prometheus 导出器?

使用https开发的golang路由