2012-04-17 3 views
1

すべてを、RSpecのとRailsコントローラーの期待

がはるかに以下のものを同様のテストでいくつかの問題を持つ:

it "does something" do 
    controller.should_receive(:some_method).once 

    expect { 
    post :create, some_params_hash, some_session_hash 
    }.to change(Something, :count).by(1) 
end 

レール側のコントローラ - ラフ例:

class SomethingsController 
    before_filter :some_method 

    def create 
    respond_with Something.create params[:something] 
    end 

    def some_method 
    puts 'some_method' 
    end 
end 

ですすべてうまく、良いとうまく動作しますの場合私はコントローラを削除します。私が期待どおりに去ったら、テストは失敗します。

これは不満足な期待では失敗しないということです。実際にはshould_receive(:some_method)の期待を満たしているようです。レコードの作成とその後の変更の評価が失敗するだけです。

そう - 質問:

これは、このテストの一部として呼び出され、コントローラへの期待を指定する適切な方法です?

ありがとうございました!

答えて

1

一般的なrspecエラーは、should_receiveによって設定されたようなメソッドの期待が、特定のことが起こるのを確実にするためにアプリケーションを監視すると考えています。しかし実際にはそれ自体をフローに挿入し、はメソッドを完全に置き換えます。

コントローラのsome_methodは、何もしないのにnilを返すコントローラに置き換えられます。また、nilを返すbeforeフィルタはすべての処理を停止します。あなたの行動は決して呼び出されません。

変更これまであなたの期待:

controller.should_receive(:some_method).once.and_return true 

はまた、あなたの例では、2つのことをテストしていることに注意してください - それはあなたのアクションがsome_methodを呼び出し、それが1で持続代の数が増加を確認しています確認しています。それは大丈夫ですが、あなたが本当に後者のみをチェックすることを意図した場合、あなたが代わりにもう少しコンパクトで期待のスタブを使用することができます。

controller.stub some_method: true 

UPDATE:私は最近のバージョンでそれを追加する必要がありますRailsでは、コントローラーフィルターの戻り値は無視されます。 (フィルターは、何かをレンダリングするだけでアクションが実行されないようにすることができます)。しかし、rspecのメソッドを置き換えるrspecの原則は、依然として真実であり、一般的に適用可能です。

+0

今夜は寝ることができます。ありがとうございました。 – Cory

関連する問題