リトライ処理のテストをしたかったのでやり方を調べた。 res, err := client.Do(req) if err != nil { // このときリトライするようにしているのをテストしたい } タイムアウトでもerrを返すため、clientのタイムアウトを極端に短くしてhttptest.Serverでちょっと待つようにすれば再現できるが、あまりスマートじゃない気がした。 コネクションを切断する http.Hijacker interfaceを使うことでコネクションを乗っ取ることができる。 import ( "context" "fmt" "io" "net/http" "net/http/httptest" "testing" "github.com/hashicorp/go-retryablehttp" "github.com/stretchr/testify/assert" ) func TestRetry(t *testing.T) { t.Run("リトライしたときに成功する", func(t *testing.T) { var count int ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch count { case 0: // 乗っ取り c, _, err := w.(http.Hijacker).Hijack() if err != nil { t.Fatal(err) } // コネクションを断つ c.Close() count++ return case 1: fmt.Fprintf(w, "successful response") return } })) defer ts.Close() retryClient := retryablehttp.NewClient() retryClient.Logger = nil retryClient.RetryMax = 2 retryClient.RetryWaitMax = 1 * time.Second got, err := retryClient.Get(ts.URL) b, _ := io.ReadAll(got.Body) defer got.Body.Close() assert.NoError(t, err) assert.Equal(t, "successful response", string(b)) }) }