Skip to content

Commit d245c88

Browse files
committed
update
1 parent fc8641e commit d245c88

File tree

4 files changed

+936
-3
lines changed

4 files changed

+936
-3
lines changed

source/c08/c08_03.md

+82
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,84 @@
11
# 8.3 测试技巧:网络测试
22

3+
### 1. TCP/HTTP
4+
5+
假设需要测试某个 API 接口的 handler 能够正常工作,例如 helloHandler
6+
7+
``` go 
8+
func helloHandler(w http.ResponseWriter, r *http.Request) {
9+
w.Write([]byte("hello world"))
10+
}
11+
```
12+
13+
那我们可以创建真实的网络连接进行测试:
14+
15+
```go
16+
// test code
17+
import (
18+
"io/ioutil"
19+
"net"
20+
"net/http"
21+
"testing"
22+
)
23+
24+
func handleError(t *testing.T, err error) {
25+
t.Helper()
26+
if err != nil {
27+
t.Fatal("failed", err)
28+
}
29+
}
30+
31+
func TestConn(t *testing.T) {
32+
ln, err := net.Listen("tcp", "127.0.0.1:0")
33+
handleError(t, err)
34+
defer ln.Close()
35+
36+
http.HandleFunc("/hello", helloHandler)
37+
go http.Serve(ln, nil)
38+
39+
resp, err := http.Get("http://" + ln.Addr().String() + "/hello")
40+
handleError(t, err)
41+
42+
defer resp.Body.Close()
43+
body, err := ioutil.ReadAll(resp.Body)
44+
handleError(t, err)
45+
46+
if string(body) != "hello world" {
47+
t.Fatal("expected hello world, but got", string(body))
48+
}
49+
}
50+
```
51+
52+
- `net.Listen("tcp", "127.0.0.1:0")`:监听一个未被占用的端口,并返回 Listener。
53+
- 调用 `http.Serve(ln, nil)` 启动 http 服务。
54+
- 使用 `http.Get` 发起一个 Get 请求,检查返回值是否正确。
55+
- 尽量不对 `http``net` 库使用 mock,这样可以覆盖较为真实的场景。
56+
57+
### 2. httptest
58+
59+
针对 http 开发的场景,使用标准库 `net/http/httptest` 进行测试更为高效。
60+
61+
上述的测试用例改写如下:
62+
63+
```go
64+
// test code
65+
import (
66+
"io/ioutil"
67+
"net/http"
68+
"net/http/httptest"
69+
"testing"
70+
)
71+
72+
func TestConn(t *testing.T) {
73+
req := httptest.NewRequest("GET", "http://example.com/foo", nil)
74+
w := httptest.NewRecorder()
75+
helloHandler(w, req)
76+
bytes, _ := ioutil.ReadAll(w.Result().Body)
77+
78+
if string(bytes) != "hello world" {
79+
t.Fatal("expected hello world, but got", string(bytes))
80+
}
81+
}
82+
```
83+
84+
使用 httptest 模拟请求对象(req)和响应对象(w),达到了相同的目的。

source/c08/c08_03.rst

+88
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,90 @@
11
8.3 测试技巧:网络测试
22
======================
3+
4+
1. TCP/HTTP
5+
~~~~~~~~~~~
6+
7+
假设需要测试某个 API 接口的 handler 能够正常工作,例如 helloHandler
8+
9+
.. code::  go 
10+
11+
func helloHandler(w http.ResponseWriter, r *http.Request) {
12+
w.Write([]byte("hello world"))
13+
}
14+
15+
那我们可以创建真实的网络连接进行测试:
16+
17+
.. code:: go
18+
19+
// test code
20+
import (
21+
"io/ioutil"
22+
"net"
23+
"net/http"
24+
"testing"
25+
)
26+
27+
func handleError(t *testing.T, err error) {
28+
t.Helper()
29+
if err != nil {
30+
t.Fatal("failed", err)
31+
}
32+
}
33+
34+
func TestConn(t *testing.T) {
35+
ln, err := net.Listen("tcp", "127.0.0.1:0")
36+
handleError(t, err)
37+
defer ln.Close()
38+
39+
http.HandleFunc("/hello", helloHandler)
40+
go http.Serve(ln, nil)
41+
42+
resp, err := http.Get("http://" + ln.Addr().String() + "/hello")
43+
handleError(t, err)
44+
45+
defer resp.Body.Close()
46+
body, err := ioutil.ReadAll(resp.Body)
47+
handleError(t, err)
48+
49+
if string(body) != "hello world" {
50+
t.Fatal("expected hello world, but got", string(body))
51+
}
52+
}
53+
54+
- ``net.Listen("tcp", "127.0.0.1:0")``\ :监听一个未被占用的端口,并返回
55+
Listener。
56+
- 调用 ``http.Serve(ln, nil)`` 启动 http 服务。
57+
- 使用 ``http.Get`` 发起一个 Get 请求,检查返回值是否正确。
58+
- 尽量不对 ``http`` 和 ``net`` 库使用
59+
mock,这样可以覆盖较为真实的场景。
60+
61+
2. httptest
62+
~~~~~~~~~~~
63+
64+
针对 http 开发的场景,使用标准库 ``net/http/httptest``
65+
进行测试更为高效。
66+
67+
上述的测试用例改写如下:
68+
69+
.. code:: go
70+
71+
// test code
72+
import (
73+
"io/ioutil"
74+
"net/http"
75+
"net/http/httptest"
76+
"testing"
77+
)
78+
79+
func TestConn(t *testing.T) {
80+
req := httptest.NewRequest("GET", "http://example.com/foo", nil)
81+
w := httptest.NewRecorder()
82+
helloHandler(w, req)
83+
bytes, _ := ioutil.ReadAll(w.Result().Body)
84+
85+
if string(bytes) != "hello world" {
86+
t.Fatal("expected hello world, but got", string(bytes))
87+
}
88+
}
89+
90+
使用 httptest 模拟请求对象(req)和响应对象(w),达到了相同的目的。

0 commit comments

Comments
 (0)