Goの実装に手を入れずにHTTPリクエストをmockするライブラリhttpmockとその仕組み

(2020-09-08)

jarcoal/httpmockは次のようなHTTPリクエストが飛ぶ関数に対して、

import (
	"io/ioutil"
	"net/http"
)

func Req() (string, error) {
	res, err := http.DefaultClient.Get("https://google.com")
	if err != nil {
		return "", err
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", err
	}
	return string(body), nil
}

次のように実装に手を入れずmockできるライブラリ。

import (
	"testing"

	"github.com/jarcoal/httpmock"
	"github.com/stretchr/testify/assert"
)

func TestReq(t *testing.T) {
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()
	httpmock.RegisterResponder("GET", "https://google.com",
		httpmock.NewStringResponder(200, "mocked"),
	)
	res, err := Req()
	assert.Nil(t, err)
	assert.Equal(t, "mocked", res)
}

仕組みとしてはActivate()http.DefaultTransportをMockTransportに置き換えhttp.RoundTripperインタフェースのRoundTrip()で登録したリクエストに対してレスポンスを返している。

Goのnet/http.Client.Doの内部実装をたどったメモ - sambaiz-net