1

全て、

次のようなテストでいくつかの問題があります。

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

controller.should_receive の期待を削除する、これはすべてうまくいき、うまく機能します。期待をそのままにしておくと、テストは失敗します。

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

だから - 質問:

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

助けてくれてありがとう!

4

1 に答える 1

1

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

したがって、コントローラーsome_methodは何もせずに nil を返すコントローラーに置き換えられます。また、nil を返す before フィルターはすべての処理を停止します。アクションが呼び出されることはありません。

期待を次のように変更します。

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

また、この例では 2 つのことをテストしていることにも注意してください。アクションsome_methodの呼び出しを確認することと、永続化された Somethings の数が 1 つ増えることを確認しています。それは問題ありませんが、実際に後者のみをチェックするつもりなら、期待値の代わりにスタブを使用できます。これはもう少しコンパクトです:

controller.stub some_method: true

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

于 2012-04-17T22:03:09.247 に答える