英文:
Golang mocking functions for http handler tests
问题
我正在为我的PostLoginHandler编写单元测试,并需要模拟一个会话中间件函数。在我的处理程序中,它调用session.Update(),我希望模拟返回nil。
在阅读了各种答案后,我首先的直觉是创建一个SessionManager接口,但即使如此,我仍然不清楚如何继续。
main.go:
func PostLoginHandler(c web.C, w http.ResponseWriter, r *http.Request) {
r.ParseForm()
user, pass := r.PostFormValue("username"), r.PostFormValue("password")
ctx := context.GetContext(c)
if !authorizeUser(user, pass) {
http.Error(w, "Wrong username or password", http.StatusBadRequest)
return
}
ctx.IsLogin = true
err := session.Update(ctx) // 模拟这个函数调用。
if err != nil {
log.Println(err)
return
}
http.Redirect(w, r, "/admin/", http.StatusFound)
}
main_test:
var loginTests = []struct {
username string
password string
code int
}{
{"admin", "admin", http.StatusFound},
{"", "", http.StatusBadRequest},
{"", "admin", http.StatusBadRequest},
{"admin", "", http.StatusBadRequest},
{"admin", "badpassword", http.StatusBadRequest},
}
func TestPostLoginHandler(t *testing.T) {
// setup()
ctx := &context.Context{IsLogin: false, Data: make(map[string]interface{})}
c := newC()
c.Env["context"] = ctx
for k, test := range loginTests {
v := url.Values{}
v.Set("username", test.username)
v.Set("password", test.password)
r, _ := http.NewRequest("POST", "/login", nil)
r.PostForm = v
resp := httptest.NewRecorder()
m.ServeHTTPC(c, resp, r)
if resp.Code != test.code {
t.Fatalf("TestPostLoginHandler #%v failed. Expected: %v\tReceived: %v", k, test.code, resp.Code)
}
}
}
英文:
I am writing a unit test for my PostLoginHandler and need to mock a session middleware function. In my handler it calls session.Update() that I would like to mock to return nil.
My first instinct after reading various answers was to make a SessionManager interface but even then I am unclear how to proceed.
main.go:
func PostLoginHandler(c web.C, w http.ResponseWriter, r *http.Request) {
r.ParseForm()
user, pass := r.PostFormValue("username"), r.PostFormValue("password")
ctx := context.GetContext(c)
if !authorizeUser(user, pass) {
http.Error(w, "Wrong username or password", http.StatusBadRequest)
return
}
ctx.IsLogin = true
err := session.Update(ctx) \\ mock this function call.
if err != nil {
log.Println(err)
return
}
http.Redirect(w, r, "/admin/", http.StatusFound)
}
main_test:
var loginTests = []struct {
username string
password string
code int
}{
{"admin", "admin", http.StatusFound},
{"", "", http.StatusBadRequest},
{"", "admin", http.StatusBadRequest},
{"admin", "", http.StatusBadRequest},
{"admin", "badpassword", http.StatusBadRequest},
}
func TestPostLoginHandler(t *testing.T) {
// setup()
ctx := &context.Context{IsLogin: false, Data: make(map[string]interface{})}
c := newC()
c.Env["context"] = ctx
for k, test := range loginTests {
v := url.Values{}
v.Set("username", test.username)
v.Set("password", test.password)
r, _ := http.NewRequest("POST", "/login", nil)
r.PostForm = v
resp := httptest.NewRecorder()
m.ServeHTTPC(c, resp, r)
if resp.Code != test.code {
t.Fatalf("TestPostLoginHandler #%v failed. Expected: %v\tReceived: %v", k, test.code, resp.Code)
}
}
}
答案1
得分: 4
我为你推荐一对链接:
Testing in Go - Github: 这个链接解释了如何使用mux
包来进行模拟路由和响应。
示例:
func TestUsersService_Get_specifiedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
}
)
user, _, err := client.Users.Get("u")
if err != nil {
t.Errorf("Users.Get返回错误:%v", err)
}
want := &User{ID: Int(1)}
if !reflect.DeepEqual(user, want) {
t.Errorf("Users.Get返回了%+v,期望是%+v",
user, want)
}
}
testflight: 这是一个用于向服务器发送简单HTTP请求的包,使用testflight和mux
进行模拟端点,可以进行完美的测试。
示例:
func TestPostWithForm(t *testing.T) {
testflight.WithServer(Handler(), func(r *testflight.Requester) {
response := r.Post("/post/form", testflight.FORM_ENCODED, "name=Drew")
assert.Equal(t, 201, response.StatusCode)
assert.Equal(t, "Drew created", response.Body)
})
}
英文:
I recommend you a pair of links:
Testing in Go - Github: This link explain how do a mock route with a response using mux
package.
Example:
func TestUsersService_Get_specifiedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
}
)
user, _, err := client.Users.Get("u")
if err != nil {
t.Errorf("Users.Get returned error: %v", err)
}
want := &User{ID: Int(1)}
if !reflect.DeepEqual(user, want) {
t.Errorf("Users.Get returned %+v, want %+v",
user, want)
}
}
testflight: A package for make simple http request to a server, using testflight and mux
for make mock endpoints you will can do a perfect test.
Example:
func TestPostWithForm(t *testing.T) {
testflight.WithServer(Handler(), func(r *testflight.Requester) {
response := r.Post("/post/form", testflight.FORM_ENCODED, "name=Drew")
assert.Equal(t, 201, response.StatusCode)
assert.Equal(t, "Drew created", response.Body)
})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论