在Golang中测试HTTP路由

13
我正在使用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: 服务器错误:返回 200 而不是 400 - Amit Kumar Gupta
搞定了。实际上我正在运行其他测试,但是我使用了相同的 respRec 而不是使用 httptest.NewRecorder() 创建一个新的记录器。我猜重复使用相同的 httpRecorder 存在一些限制。 - moesef
1个回答

9

这里使用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()函数吗?我们是否只能添加特定于测试的路由? - Abhijeet Padwal
抱歉,我明白了,问题中已经有答案了。 - Abhijeet Padwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接