如何编写基于net/http的代码的集成测试?

4
这里有一个示例代码:

package main

import (
    "net/http"
)

func Home(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello, world!"))
}

func Router() *http.ServeMux {
    mux := http.NewServeMux()
    mux.HandleFunc("/", Home)
    return mux
}

func main() {
    mux := Router()
    http.ListenAndServe(":8080", mux)
}

这是我编写的测试用例:
package main

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestMain(t *testing.T) {
    w := httptest.NewRecorder()
    r, _ := http.NewRequest("GET", "/", nil)
    Router().ServeHTTP(w, r)
    if w.Body.String() != "Hello, world!" {
        t.Error("Wrong content:", w.Body.String())
    }
}

这个测试是否真的通过TCP套接字发送了HTTP请求并到达了终点/?还是只是调用函数而没有建立HTTP连接?

更新

根据@ffk给出的答案,我将测试编写如下:

func TestMain(t *testing.T) {
    ts := httptest.NewServer(Router())
    defer ts.Close()
    req, _ := http.NewRequest("GET", ts.URL+"/", nil)
    client := http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    if string(body) != "Hello, world!" {
        t.Error("Wrong content:", string(body))
    }
}

你文本中的两个问题实际上与问题标题不符。 - Stephan Dollberg
@inf 我期待使用 net/http 在Go语言中编写集成测试。上述代码是我计划以此为基础。通过最后两个问题,我试图解释我需要测试的关键集成。您是否有任何建议来改进标题或最后两个问题? - baijum
1
你的示例测试并没有发起实际的 HTTP 请求。httptest.NewRecorder() 只是创建了一个 http.ResponseWriter 的实现,让你记录下你的 HTTP 处理程序所写的内容。这是一种很好的测试 HTTP 路由的方法。另一种方法是在测试中构建和运行你的代码,并发起实际的 HTTP 请求。 - jmaloney
@jmaloney 谢谢您的建议。我会继续采用这种方法,因为它看起来更容易编写。 - baijum
别忘了检查错误! - Dave C
1个回答

1

如果您想在127.0.0.1上实例化一个可通过随机TCP端口访问的测试服务器,请使用以下内容:

httpHandler := getHttpHandler() // of type http.Handler
testServer := httptest.NewServer(httpHandler)
defer testServer.Close()
request, err := http.NewRequest("GET", testServer.URL+"/my/url", nil)
client := http.Client{}
response, err := client.Do(request)

更多信息请参见https://golang.org/pkg/net/http/httptest/#NewServer


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