暇人じゃない

WebMock でリクエストごとにレスポンスを変更する
RSpec

RSpec などで外部 API のリクエストを WebMock を使ってスタブしている環境で、リクエストごとにレスポンスを変更したいときのメモ。

以下のように、.to_return に複数のレスポンスを記述することで、リクエストごとにレスポンスを変更することができる。

stub_request(:get, "https://example.com").
  to_return(
    { body: "1", status: 200 },
    { body: "2", status: 400 },
    { body: "3", status: 500 },
  )

.to_return を複数記述してもよい。

stub_request(:get, "https://example.com").
  to_return(body: "1", status: 200).
  to_return(body: "2", status: 400).
  to_return(body: "3", status: 500)

.times を使うことで少しだけシンプルに「ステータスコード 200 を 2 回返し、それ以降はステータスコード 400 を返す」といったスタブを定義することが可能。

stub_request(:get, "https://example.com").
  to_return(status: 200).times(2).
  to_return(status: 400)

詳しくは WebMock のテストケースをどうぞ。

サンプル

実装は以下を想定。

def request
  Faraday.get("https://example.com")
end

テストケースは以下。

describe "#request" do
  before do
    stub_request(:get, "https://example.com").to_return(
      { body: "1", status: 200 },
      { body: "2", status: 400 },
      { body: "3", status: 500 },
    )
  end

  it do
    expect(request.status).to eq(200)
    expect(request.status).to eq(400)
    expect(request.status).to eq(500)

    # 定義したスタブ以上のリクエストは最後に定義したスタブが返される
    expect(request.status).to eq(500)
  end
end

About

chocoby (GitHub / Twitter)

個人事業主のソフトウェア開発者です。 Ruby と Rails を使った Web サービスの開発を得意としています。

CurryBu というサービスや、jp_prefecture という Gem を作っています。