web-dev-qa-db-ja.com

http.Client Doメソッドをモックする方法

私はテストとモックHTTP応答を作成するソリューションを見つけようとしています。インターフェイスを受け入れる私の機能では:

type HttpClient interface {
    Do(req *http.Request) (*http.Response, error)
}

ベース認証でhttp getリクエストを作成します

func GetOverview(client HttpClient, overview *Overview) (*Overview, error) {

    request, err := http.NewRequest("GET", fmt.Sprintf("%s:%s/api/overview", overview.Config.Url, overview.Config.Port), nil)
    if (err != nil) {
        log.Println(err)
    }
    request.SetBasicAuth(overview.Config.User, overview.Config.Password)
    resp, err := client.Do(request)

このHttpClientをモックするにはどうすればよいですか?例えば、モックライブラリを探しています: https://github.com/h2non/gock しかし、GetとPostのモックしかありません

たぶん私は別の方法でそれをする必要があります。アドバイスに感謝します

24
quentino

インターフェイスにあるシグネチャに一致するメソッドを持つ構造体は、インターフェイスを実装します。たとえば、構造体ClientMockを作成できます

type ClientMock struct {
}

メソッドで

func (c *ClientMock) Do(req *http.Request) (*http.Response, error) {
    return &http.Response{}, nil
}

次に、このClientMock構造体をGetOverview funcに挿入できます。 ここ はGo Playgroundの例です。

25
Gavin

net/http/httptest パッケージはあなたの親友です:

// generate a test server so we can capture and inspect the request
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
    res.WriteHeader(scenario.expectedRespStatus)
    res.Write([]byte("body"))
}))
defer func() { testServer.Close() }()

req, err := http.NewRequest(http.MethodGet, testServer.URL, nil)
assert.NoError(t, err)

res, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.Equal(t, scenario.expectedRespStatus, res.StatusCode, "status code should match the expected response")
15
rocketspacer

私はそれが少しの間だったことを知っていますが、私は最近これを助けるために何かを書きました。

一般に、HTTPリクエストをモックするには、Goで簡単に実行できるため、実際のHTTPサーバーをローカルで起動することをお勧めします。 https://golang.org/pkg/net/http/httptest/ は、それを行うための非常に標準的な方法です(サーバータイプで指定されたサンプルコードを参照)。

しかし、多くのHTTPモックを行ったので、良いモックライブラリのように、もう少し機能するものが欲しいと思っていました。期待の簡単な設定、すべてのリクエストが行われたことの検証などです。私は一般的に https:// godocを使用しました。 org/github.com/stretchr/testify/mock モックやそのような機能が必要です。

そこで私は https://github.com/dankinder/httpmock を書きました。これは基本的に2つを組み合わせたものです。

3
Dan

インターフェイスに一致するメソッドで構造体を作成する必要があります。モックは一般にテスト目的で使用されるため、モックメソッドの戻り値を準備する機能が必要です。これを実現するために、メソッドに対応するfunc属性を持つ構造体を作成します。

インターフェースは次のとおりです。

type HttpClient interface {
    Do(req *http.Request) (*http.Response, error)
}

同等のモック:

type MockClient struct {
    DoFunc func(req *http.Request) (*http.Response, error)
}

func (m *MockClient) Do(req *http.Request) (*http.Response, error) {
    if m.DoFunc != nil {
        return m.DoFunc(req)
    }
    return &http.Response{}, nil
}

それから、次のステップはいくつかのテストを書くことです。例 ここ

2
mwarzynski