Rails/Rspec - 如何在不重做工作的情况下使用多个它

Rails/Rspec - How to use multiple it without redoing work

多次我想通过同一个动作检查多个东西,比如我想做一个 PUT 并查看请求是否返回 200 以及响应值是否包含一些值以及 ActiveRecord 模型已更新。

在下一个示例中,我尝试使用 before,但它 运行 就在每个 it 之前。

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 次,并且每次都验证它的内容。 通过这种方法,我可以清楚地看到失败的原因。

另一种方法是删除每个 it 并且只有 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

但是这种方法并没有在失败时立即告诉我失败的原因。

我怎样才能做到这一点而不必为每个 it 块执行 before

您可能正在寻找 before(:context)

before(:context) do
  put my_url
end

context "with valid params" do
  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(:context)anti-pattern

你可以这样做

而不是 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到aggregate failures

你可以it per block

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

或设置globally for your project,还有其他选项,选择你最喜欢的。