测试Golang中的HTTP路由

huangapple go评论93阅读模式
英文:

Testing HTTP routes in Golang

问题

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

package routes

// 导入一些包

// 一些代码

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

// 导入一些包

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

func init() {
    // 带有添加的问题路由的mux路由器
    m = mux.NewRouter()
    AddQuestionRoutes(m)

    // 用于记录HTTP响应的响应记录器
    respRec = httptest.NewRecorder()
}

func TestGet400(t *testing.T) {
    // 测试获取不存在的问题类型
    req, err = http.NewRequest("GET", "/questions/1/SC", nil)
    if err != nil {
        t.Fatal("创建 'GET /questions/1/SC' 请求失败!")
    }

    m.ServeHTTP(respRec, req)

    if respRec.Code != http.StatusBadRequest {
        t.Fatal("服务器错误:返回", respRec.Code, "而不是", http.StatusBadRequest)
    }
}

然而,当我运行这个测试时,我得到了一个404错误,可能是因为请求没有被正确路由。当我从浏览器测试这个GET路由时,确实返回了400,所以我确定测试的设置存在问题。

英文:

I am using Gorilla mux and the net/http package to create some routes as follows

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")
}

I am trying to write a test to test these routes. For example, I am trying to test the GET route specifically trying to get a 400 returned so I have the following test code.

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)
	}
}

However, when I run this test, I get a 404 conceivably because the request is not being routed correctly.?

When I test this GET route from the browser, it does return a 400 so I'm certain there is an issue with the way the test is setup.

答案1

得分: 9

在这里使用init()是可疑的。它只在程序初始化时执行一次。相反,可以尝试像这样的代码:

func setup() {
    //mux路由器与添加的问题路由一起使用
    m = mux.NewRouter()
    AddQuestionRoutes(m)

    //用于记录HTTP响应的响应记录器
    respRec = httptest.NewRecorder()
}

func TestGet400(t *testing.T) {
    setup()
    //测试获取不存在的问题类型
    req, err = http.NewRequest("GET", "/questions/1/SC", nil)
    if err != nil {
        t.Fatal("创建 'GET /questions/1/SC' 请求失败!")
    }

    m.ServeHTTP(respRec, req)

    if respRec.Code != http.StatusBadRequest {
        t.Fatal("服务器错误:返回了", respRec.Code, "而不是", http.StatusBadRequest)
    }
}

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

如果你需要一个提供更多功能的测试框架,比如设置/拆卸夹具,请参考像gocheck这样的包。

英文:

The use of init() here is suspect. It only executes once as part of program initialization. Instead, perhaps something like:

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)
    }
}

where you call setup() at the beginning of each appropriate test case. Your original code was sharing the same respRec with other tests, which probably polluted your test results.

If you need a testing framework that provides more features like setup/teardown fixtures, see packages such as gocheck.

huangapple
  • 本文由 发表于 2014年8月16日 13:10:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/25337126.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定