6

この仕様をproducts_controller_spec.rbに記述しました。これは、存在しないレコードでdestroyが呼び出されたときにリダイレクトをテストすることを目的としています。

it "deleting a non-existent product should redirect to the user's profile page with a flash error" do           
    delete :destroy, {:id => 9999}
    response.should redirect_to "/profile"
    flash[:error].should == I18n.t(:slideshow_was_not_deleted)
end

これがproducts_controller.rbのコントローラーアクションです。

def destroy
  product = Product.find_by_id(params[:id])
  redirect_to "profile" if !product
  if product.destroy
    flash[:notice] = t(:slideshow_was_deleted)
    if current_user.admin? and product.user != current_user
      redirect_to :products, :notice => t(:slideshow_was_deleted)
    else
      redirect_to "/profile"
    end
  else
    if current_user.admin?
      redirect_to :products, :error => t(:slideshow_was_not_deleted)
    else
      redirect_to "/profile"
    end
  end
end

さて、私はスペックが最初に合格することを期待していませんでしたが、なぜそれがこれで失敗するのか理解できません:

Failure/Error: delete :destroy, {:id => 9999}
 ActiveRecord::RecordNotFound:
   Couldn't find Product with id=9999

#find_by_idは、存在しないレコードに対してRecordNotFoundエラーを返さないという印象を受けました。では、なぜ私はそれを手に入れているのですか?前もって感謝します!

4

1 に答える 1

16

RecordNotFoundエラーがCanCanによってスローされていました。コントローラアクション内からはレスキューできません(おそらく、アクションが実行される前に発生します)。それを解決する方法は2つありました-

  1. 仕様を次のように変更します。

    it "deleting a non-existent product should result in a RecordNotFound Error" do         
      product_id = 9999
      expect { delete :destroy, {:id => product_id}}.to raise_error ActiveRecord::RecordNotFound
    end
    

または、2。このようにCanCanにパッチを適用します。

パッチ適用ルートが気に入らなかったので、オプション1を選択しました。

于 2012-04-17T21:09:49.177 に答える