Techioz Blog

Rails/Rspec - 作業をやり直さずに複数の it を使用する方法

概要

同じアクションで複数のことを確認したいことが何度もあります。たとえば、PUT を実行して、リクエストが 200 を返したかどうか、応答値に値が含まれているかどうか、ActiveRecord モデルが更新されたかどうかを確認したいとします。

次の例では、以前に使用してみましたが、それぞれの直前に実行されます。

context "with valid params" do
  before do
    put my_url
  end

  it "returns a 200 response" do
    expect(response).to have_http_status(200)
  end

  it "updates the right values" do
    expect(my_model.min_area).to eq(111)
    expect(my_model.max_area).to eq(222)
  end

  it "dont update a param if it is not sent" do
    expect(my_model.budget).to eq(333)
  end
end

before ブロックを 1 回だけ実行して、そのたびに内容を確認したいと考えています。 このアプローチを使用すると、失敗したときに何が失敗したかが明確にわかります。

それを行う他の方法は、それぞれを削除し、次のように 1 つだけを持つことです。

context "with valid params" do
  it "updates all" do
    put my_url

    expect(response).to have_http_status(200)
    expect(my_model.min_area).to eq(111)
    expect(my_model.max_area).to eq(222)
    expect(my_model.budget).to eq(333)
  end
end

しかし、このアプローチでは、失敗したときに何が失敗したかがすぐにわかりません。

ブロックごとに before を実行せずにこれを行うにはどうすればよいですか?

解決策

before(:context) の代わりにこれを行うこともできます

context "with valid params" do
  it "updates all" do
    put my_url

    expect(response).to have_http_status(200)
    expect(my_model.min_area).to eq(111)
    expect(my_model.max_area).to eq(222)
    expect(my_model.budget).to eq(333)
  end
end

ただし、必要なのは、RSpec に障害を集約するように指示することです

ブロックごとに実行できます

context "with valid params", :aggregate_failures do
  it "updates all" do
    put my_url

    expect(response).to have_http_status(200)
    expect(my_model.min_area).to eq(111)
    expect(my_model.max_area).to eq(222)
    expect(my_model.budget).to eq(333)
  end
end

または、プロジェクトに対してグローバルに設定することもできます。その他のオプションも利用できるので、最も好きなものを選択してください。