在这节我们将学习如果用 Go 测试 HTTP handlers,这是一个用 Go 测试的特别例子。我们将已 www.go
的代码为基础,修改需要调整的地方。
新版本的 www.go
命名为 testWWW.go
,并分为三部分展示。testWWW.go
的第一部分代码如下:
Copy package main
import (
"fmt"
"net/http"
"os"
)
func CheckStatusOK (w http . ResponseWriter , r * http . Request ){
w. WriteHeader (http.StatusOK)
fmt. Fprintf (w, `Fine!` )
}
testWWW.go
的第二部分代码如下:
Copy func StatusNotFound (w http . ResponseWriter , r * http . Request ) {
fmt. Fprintf (w, "Serving: %s \n" , r.URL.Path)
fmt. Printf ( "Served: %s \n" , r.Host)
}
func MyHandler (w http . ResponseWriter , r * http . Request ) {
fmt. Fprintf (w, "Serving: %s \n" , r.URL.Path)
fmt. Printf ( "Served: %s \n" , r.Host)
}
testWWW.go
余下代码如下:
Copy func main () {
PORT := ":8001"
arguments := os.Args
if len (arguments) == 1 {
fmt. Println ( "Using default port number:" , PORT)
} else {
PORT = ":" + arguments[ 1 ]
}
http. HandleFunc ( "/CheckStatusOK" , CheckStatusOK)
http. HandleFunc ( "/StatusNotFound" , StatusNotFound)
http. HandleFunc ( "/" , MyHandler)
err := http. ListenAndServe (PORT, nil )
if err != nil {
fmt. Println (err)
return
}
}
我们现在需要开始测试 testWWW.go
了,为此我们应该创建一个 testWWW_test.go
文件。这个文件的内容由四部分展示。
testWWW_test.go
的第一部分包容如下代码:
Copy package main
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
注意,为了用 Go 测试 web 应用,您需要引入 net/http/httptest
标准包。
testWWW_tesst.go
的第二部分如下:
Copy func TestCheckStatusOK (t * testing . T ) {
req, err := http. NewRequest ( "GET" , "/CheckStatusOK" , nil )
if err != nil {
fmt. Println (err)
return
}
rr := httptest. NewRecorder ()
handler := http. HandlerFunc (CheckStatusOK)
handler. ServeHTTP (rr, req)
httptest.NewRecorder()
函数返回一个 httptest.ResponseRecorder
对象,它被用于记录 HTTP 响应。
testWWW_test.go
的第三部分如下:
Copy status := rr.Code
if status != http.StatusOK {
t. Errorf ( "handler returned %v " , status)
}
expect := `Fine!`
if rr.Body. String () != expect {
t. Errorf ( "handler returned %v " , rr.Body. String ())
}
}
您首先检查返回码是所期望的,然后再验证返回消息体也是您期望的。
testWWW_test.go
的余下代码如下:
Copy func TestStatusNotFound (t * testing . T ) {
req, err := http. NewRequest ( "GET" , "/StatusNotFound" , nil )
if err != nil {
fmt. Println (err)
return
}
rr := httptest. NewRecorder ()
handler := http. HandlerFunc (StatusNotFound)
handler. ServeHTTP (rr, req)
status := rr.Code
if status != http.StatusNotFound {
t. Errorf ( "handler returned %v " , status)
}
}
这个测试函数验证 main
包中的 StatusNotFound()
函数是否如期运行。
执行 testWWW_test.go
的这俩个测试函数将产生如下输出:
Copy $ go test testWWW.go testWWW_test.go -v
=== RUN TestCheckStatusOK
--- PASS: TestCheckStatusOK (0.00s)
=== RUN TestStatusNotFound
--- PASS: TestStatusNotFound (0.00s)
PASS
ok command-line-arguments (cached)