猿问

无需重置路由的最小 http 服务测试?

假设我有一个非常简单的 Web 服务。


func main() {

    http.HandleFunc("/", sanityTest)

    log.Fatal(http.ListenAndServe(":8000", nil))

}

如果我想测试它,我至少可以拥有:


func ExampleTest() {

        server := httptest.NewServer(http.DefaultServeMux)

        defer server.Close()


        resp, err := http.Get(server.URL)

        if err != nil {

                log.Fatal(err)

        }

        body, _ := ioutil.ReadAll(resp.Body)


        fmt.Println(resp.StatusCode)

        fmt.Println(resp.Header.Get("Content-Type"))

        fmt.Println(string(body))


        // Output:

        // 200

        // text/plain; charset=utf-8

        // OK


}

但这将导致 404,因为它不知道路由。所以我看到 main_test.go 代码所做的是在测试文件的 init 中重新设置句柄,如下所示:


func init() {

    http.HandleFunc("/", sanityTest)

}

这会导致重复,不可避免地我必须在 main.go 中创建一个函数,例如:


func setupRoutes() {

        http.HandleFunc("/", sanityTest)

}

我觉得有点难看。我是否缺少从 main.go 实例化路由并避免 init 的技巧?


红糖糍粑
浏览 90回答 1
1回答

白衣非少年

您可以在测试和 main.go 文件之间重复使用路由,如果您想在处理程序中模拟某些内容,这也很有帮助(在router()下面的 func 中添加一个新参数)主要去:func sanityTest(w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "%s", "sanity test")}func router() *http.ServeMux {    h := http.NewServeMux()    h.HandleFunc("/", sanityTest)    return h}func main() {    http.ListenAndServe(":8080", router())}main_test.go:func TestSanity(t *testing.T) {    tests := []struct {        name string        uri  string        want string    }{        {"1", "/", "sanity test"},    }    ts := httptest.NewServer(router())    defer ts.Close()    for _, tt := range tests {        t.Run(tt.name, func(t *testing.T) {            url := ts.URL + tt.uri            resp, _ := http.Get(url)            respBody, _ := ioutil.ReadAll(resp.Body)            resp.Body.Close()            got := string(respBody)            if got != tt.want {                t.Errorf("got %s, Want %s", got, tt.want)            }        })    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答