ruby-on-rails - Ruby on Rails - RSpec - 重构 lambda 样式测试

标签 ruby-on-rails ruby rspec refactoring

我很确定我可以使这个测试更干净,一直在搜索但无法破解它。测试通过了,但我想重构。

describe "as an authenticated user that made the offer" do
    before { log_in offering_user; }
    specify { expect { delete :destroy, id: offer.id }.to change(Offer, :count).by(-1) }
    describe "redirect and flash" do
      before { delete :destroy, id: offer.id }
      specify { response.should redirect_to item_path(offer.receiving_item) }
      specify { flash[:success].should_not be_nil }
    end
end

看看我如何必须在规范中提出两次请求?这也迫使我使用另一个描述 block 。理想情况下,我可以在第一个 before block 中发出请求,并执行以下操作:

it { should change(Offer, :count).by(-1) }

有人能指出我正确的方向吗?谢谢。

最佳答案

如果您不介意重构测试以使用 expect 语法 ( recommended ),并在同一测试中测试多个条件,您可以执行以下操作:

describe "as an authenticated user that made the offer" do
  let(:destroying_an_offer) { -> { delete :destroy, id: offer.id } }
  before { log_in offering_user }

  it "destroys offer" do
    expect(destroying_an_offer).to change(Offer, :count).by(-1)
    expect(response).to redirect_to(item_path(offer.receiving_item))
    expect(flash[:success]).to_not be_nil
  end
end

第一个 expect 将发出 delete 请求,其余的 expect 将在后续操作。

如果您想使用 should 语法,我认为您无法避免多次发出请求,因此很难将它们进一步重构为您的眼镜。不过,值得深思的是,如果您想具体指定应用程序受请求影响的不同方面,您甚至可以对每个规范进行 subject 更改,以获得每个规范的单一聚焦 it block :

describe "as an authenticated user that made the offer" do
  before do
    log_in offering_user
    delete :destroy, id: offer.id
  end

  describe "behaviour" do
    subject { response }
    it { should redirect_to item_path(offer.receiving_item) }
  end

  describe "appearance" do
    subject { flash[:success] }
    it { should_not be_nil }
  end

  describe "result" do
    subject { -> { delete :destroy, id: offer.id } }
    it { should change(Offer, :count).by(-1) }
  end
end

关于ruby-on-rails - Ruby on Rails - RSpec - 重构 lambda 样式测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16804547/

相关文章:

ruby-on-rails - 具有 Devise 身份验证的 Apipie

mysql - Rails `where` 时间少于查询

ruby - RSpec 和 Open-URI 我如何模拟引发 SocketError/TimeoutError

ruby-on-rails - 如何在任何异常情况下使用 RSpec 的 should_raise?

ruby-on-rails - 设计劫持 401 响应

ruby-on-rails - RSpec:时间比较未通过

ruby - 可移植 Ruby GUI 工具包

ruby-on-rails - 有没有更好的方法来检查子参数?

ruby 没有像 Fiber.kill 那样的东西吗?

ruby-on-rails - rails/rspec 看不到 shoulda 匹配器