2 回答
TA贡献1805条经验 获得超9个赞
独立于原始问题,您不应该为每个请求创建新的 HTTP 客户端。客户端维护一个连接池,应尽可能重用。
您可以解决这个问题,并通过注入 HTTP 客户端继续使用现有的模拟服务器。
另请注意,问题中的接口定义与实现不匹配。这两个方法签名是不一样的:
HttpReq(params) ([]byte, error) // Req HttpReq(*params) ([]byte, error) // Impl
选一个。我可能会在这里使用非指针类型。大写首字母在 Go 中是惯用的(HTTPReq
, not HttpReq
)。
将客户端添加到Impl
类型中并将其用于HTTPReq
:
type Impl struct {
client *http.Client
}
func (i *Impl) HTTPReq(p params) ([]byte, error) {
req, err := http.NewRequest(p.method, p.url, nil)
if err != nil {
return nil, err
}
req.SetBasicAuth(p.cs, p.ci)
res, err := i.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
return ioutil.ReadAll(res.Body)
}
服务类型不必更改。
在测试中,只需将测试客户端注入到Impl值中:
import (
"context"
"net"
"net/http"
"net/http/httptest"
"testing"
)
func TestService_execute(t *testing.T) {
var testHandler http.Handler // TODO
srv := httptest.NewServer(testHandler)
defer srv.Close()
client := srv.Client()
tp := client.Transport.(*http.Transport)
// Direct all requests to the test server, no matter what the request URL is.
tp.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
// Note that we ignore the network and addr parameters, since these are
// derived from the request URL and are unrelated to the test server.
srvAddr := srv.Listener.Addr()
return (&net.Dialer{}).DialContext(ctx, srvAddr.Network(), srvAddr.String())
}
svc := &Service{
req: &Impl{
client: client,
},
}
svc.execute(/* ... */)
// assert request, response, etc.
}
- 2 回答
- 0 关注
- 124 浏览
添加回答
举报