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

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

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

问题

这是一个示例代码:

  1. package main
  2. import (
  3. "net/http"
  4. )
  5. func Home(w http.ResponseWriter, r *http.Request) {
  6. w.Write([]byte("Hello, world!"))
  7. }
  8. func Router() *http.ServeMux {
  9. mux := http.NewServeMux()
  10. mux.HandleFunc("/", Home)
  11. return mux
  12. }
  13. func main() {
  14. mux := Router()
  15. http.ListenAndServe(":8080", mux)
  16. }

这是我编写的测试用例:

  1. package main
  2. import (
  3. "net/http"
  4. "net/http/httptest"
  5. "testing"
  6. )
  7. func TestMain(t *testing.T) {
  8. w := httptest.NewRecorder()
  9. r, _ := http.NewRequest("GET", "/", nil)
  10. Router().ServeHTTP(w, r)
  11. if w.Body.String() != "Hello, world!" {
  12. t.Error("Wrong content:", w.Body.String())
  13. }
  14. }

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

更新

根据@ffk给出的答案,我将测试代码修改为:

  1. func TestMain(t *testing.T) {
  2. ts := httptest.NewServer(Router())
  3. defer ts.Close()
  4. req, _ := http.NewRequest("GET", ts.URL+"/", nil)
  5. client := http.Client{}
  6. resp, _ := client.Do(req)
  7. defer resp.Body.Close()
  8. body, _ := ioutil.ReadAll(resp.Body)
  9. if string(body) != "Hello, world!" {
  10. t.Error("Wrong content:", string(body))
  11. }
  12. }
英文:

Here is an example code:

  1. package main
  2. import (
  3. "net/http"
  4. )
  5. func Home(w http.ResponseWriter, r *http.Request) {
  6. w.Write([]byte("Hello, world!"))
  7. }
  8. func Router() *http.ServeMux {
  9. mux := http.NewServeMux()
  10. mux.HandleFunc("/", Home)
  11. return mux
  12. }
  13. func main() {
  14. mux := Router()
  15. http.ListenAndServe(":8080", mux)
  16. }

This is the test case I wrote:

  1. package main
  2. import (
  3. "net/http"
  4. "net/http/httptest"
  5. "testing"
  6. )
  7. func TestMain(t *testing.T) {
  8. w := httptest.NewRecorder()
  9. r, _ := http.NewRequest("GET", "/", nil)
  10. Router().ServeHTTP(w, r)
  11. if w.Body.String() != "Hello, world!" {
  12. t.Error("Wrong content:", w.Body.String())
  13. }
  14. }

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:

  1. func TestMain(t *testing.T) {
  2. ts := httptest.NewServer(Router())
  3. defer ts.Close()
  4. req, _ := http.NewRequest("GET", ts.URL+"/", nil)
  5. client := http.Client{}
  6. resp, _ := client.Do(req)
  7. defer resp.Body.Close()
  8. body, _ := ioutil.ReadAll(resp.Body)
  9. if string(body) != "Hello, world!" {
  10. t.Error("Wrong content:", string(body))
  11. }
  12. }

答案1

得分: 1

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

  1. httpHandler := getHttpHandler() // 类型为 http.Handler
  2. testServer := httptest.NewServer(httpHandler)
  3. defer testServer.Close()
  4. request, err := http.NewRequest("GET", testServer.URL+"/my/url", nil)
  5. client := http.Client{}
  6. 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:

  1. httpHandler := getHttpHandler() // of type http.Handler
  2. testServer := httptest.NewServer(httpHandler)
  3. defer testServer.Close()
  4. request, err := http.NewRequest("GET", testServer.URL+"/my/url", nil)
  5. client := http.Client{}
  6. 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:

确定