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

huangapple go评论92阅读模式
英文:

How to write integration tests for net/http based code?

问题

这是一个示例代码:

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))
	}
}
英文:

Here is an example code:

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)
}

This is the test case I wrote:

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())
	}
}

Is this test really sending an HTTP request through a TCP socket and reaching the end point /? Or this is just calling the function without making an HTTP connection?

Update

Based on the answer given by @ffk I wrote the test like this:

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))
	}
}

答案1

得分: 1

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

httpHandler := getHttpHandler() // 类型为 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

英文:

If you want to instantiate a test server accessible over a random tcp port on 127.0.0.1, use the following:

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)

For more info, see https://golang.org/pkg/net/http/httptest/#NewServer

huangapple
  • 本文由 发表于 2015年5月20日 02:00:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/30332873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定