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 關注
- 167 瀏覽
添加回答
舉報