2

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

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

看看我是如何不得不在规范中提出两次请求的?这也迫使我使用另一个描述块。理想情况下,我可以在第一个before块中提出请求,并有一些类似的东西

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

谁能指出我正确的方向?谢谢。

4

2 回答 2

2

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

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请求,其余的expects 将在善后进行操作。

如果您想使用该should语法,我认为您将无法避免多次发出请求,因此很难根据您的规范进一步重构它们。不过,作为一个值得深思的地方,如果您想明确指出受请求影响的应用程序的不同方面,您甚至可以对每个规范进行subject更改,以便为每个规范获得一个单一的焦点it块:

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
于 2013-05-29T12:35:21.773 回答
1

为了使用带有 lambda 表示法的隐式主题,您可以执行以下操作:

describe "as an authenticated user that made the offer" do
  before { log_in offering_user }
  subject { -> { delete :destroy, id: offer.id } }
  it { should change {Offer.count}.by(-1) }
end

我还没有看到如何结束这个测试:)

于 2013-05-29T11:12:32.813 回答