说我有一个非常简单的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?
答案 0 :(得分:2)
您可以重用测试和main.go文件之间的路由,如果您想在处理程序中模拟某些东西(在下面的router()
func中添加新的参数),这也很有帮助
main.go:
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)
}
})
}
}