httptest 简介在 golang 的测试框架中,httptest 的主要作用就是帮助测试者模拟 http 请求和响应,从而方便地对服务端的 api 接口进行测试。它不依赖于网络和实际的 http 服务器,而是使用 golang 提供的 net/http 包中的功能,模拟出请求和响应的整个流程。
httptest 常用方法(1)创建测试服务器
在 httptest 中,我们需要通过 newserver 方法创建一个测试服务器。该方法的参数需要传入一个实现了 http.handler 接口的 handlerfunc。例如,我们可以创建一个处理 get 请求的 handlerfunc,并通过它创建一个测试服务器:
func testgetfoo(t *testing.t) { srv := httptest.newserver(http.handlerfunc(func(w http.responsewriter, r *http.request) { w.writeheader(http.statusok) fmt.fprintln(w, hello, world!) })) defer srv.close() resp, err := http.get(srv.url) if err != nil { t.fatal(err) } defer resp.body.close() if resp.statuscode != http.statusok { t.errorf(expected %d but got %d, http.statusok, resp.statuscode) }}
(2)发送请求
有了测试服务器之后,我们就可以通过 client 来向服务器发送请求。client 是 golang 提供的一个 http 请求客户端。例如,我们可以创建一个处理 post 请求的 handlerfunc,并通过它创建一个测试服务器。然后发送一个 post 请求,包含 json 数据:
func testpostjson(t *testing.t) { srv := httptest.newserver(http.handlerfunc(func(w http.responsewriter, r *http.request) { body, _ := ioutil.readall(r.body) w.writeheader(http.statusok) fmt.fprintln(w, string(body)) })) defer srv.close() payload := struct { name string `json:name` age int `json:age` }{ name: robert, age: 30, } buf, _ := json.marshal(payload) resp, err := http.post(srv.url, application/json, bytes.newreader(buf)) if err != nil { t.fatal(err) } defer resp.body.close() if resp.statuscode != http.statusok { t.errorf(expected %d but got %d, http.statusok, resp.statuscode) } body, _ := ioutil.readall(resp.body) if string(body) != `{name:robert,age:30}` { t.errorf(expected %s but got %s, `{name:robert,age:30}`, string(body)) }}
(3)设置请求头和响应头
在测试中,请求头和响应头也是很重要的一部分。我们可以通过 header 方法来设置请求头和响应头。例如,我们可以创建一个处理 get 请求的 handlerfunc,并通过它创建一个测试服务器。然后设置请求头和响应头:
func testheader(t *testing.t) { srv := httptest.newserver(http.handlerfunc(func(w http.responsewriter, r *http.request) { w.header().set(x-test, hello) w.writeheader(http.statusok) fmt.fprintln(w, hello, world!) })) defer srv.close() req, err := http.newrequest(get, srv.url, nil) if err != nil { t.fatal(err) } req.header.add(x-test, world) resp, err := http.defaultclient.do(req) if err != nil { t.fatal(err) } defer resp.body.close() if resp.statuscode != http.statusok { t.errorf(expected %d but got %d, http.statusok, resp.statuscode) } if resp.header.get(x-test) != hello { t.errorf(expected %s but got %s, hello, resp.header.get(x-test)) }}
(4)处理 https 请求
在实际的项目中,很多 http 接口都需要通过 https 进行安全传输。在 httptest 中,我们也可以通过 newtlsserver 方法来创建一个支持 https 的测试服务器。新建的服务器使用自签名证书,因此不应该在生产环境中使用。例如,我们可以创建一个处理 post 请求的 handlerfunc,并通过它创建一个支持 https 的测试服务器。然后发送一个 post 请求,包含 json 数据:
func testtlspostjson(t *testing.t) { srv := httptest.newtlsserver(http.handlerfunc(func(w http.responsewriter, r *http.request) { body, _ := ioutil.readall(r.body) w.writeheader(http.statusok) fmt.fprintln(w, string(body)) })) defer srv.close() payload := struct { name string `json:name` age int `json:age` }{ name: robert, age: 30, } buf, _ := json.marshal(payload) client := srv.client() resp, err := client.post(srv.url, application/json, bytes.newreader(buf)) if err != nil { t.fatal(err) } defer resp.body.close() if resp.statuscode != http.statusok { t.errorf(expected %d but got %d, http.statusok, resp.statuscode) } body, _ := ioutil.readall(resp.body) if string(body) != `{name:robert,age:30}` { t.errorf(expected %s but got %s, `{name:robert,age:30}`, string(body)) }}
httptest 的注意事项尽管 httptest 在 golang 测试框架中很方便实用,但使用不当仍然可能会导致测试结果不准确。我们需要注意以下几点:
(1)httptest 不应当被用作生产环境下的 http 或 https 服务器,仅用于测试目的。
(2)如果测试服务器没有被正确关闭,可能会因为测试套件过多而导致资源耗尽。
(3)如果使用 httptest 提交到的数据和你所提交的数据不匹配,你将无法得到正确的测试结果。
总结在 golang 的测试过程中,httptest 是一个非常有用的工具,可以帮助我们模拟 http 请求和响应,从而方便地对服务端的 api 接口进行测试。本文中,我们详细介绍了 httptest 的基本概念、用法和注意事项,希望能对 golang 开发者们在接下来的测试工作中有所帮助。
以上就是golang httptest用法是什么的详细内容。
