質問

このような状況では何も見つかりませんでした。このように定義された名前付きスコープを持つモデルがあります:

class Customer < ActiveRecord::Base
  # ...
  named_scope :active_customers, :conditions => { :active => true }
end

そして、私はコントローラーの仕様でそれを書き留めようとしています:

# spec/customers_controller_spec.rb
describe CustomersController do
  before(:each) do
    Customer.stub_chain(:active_customers).and_return(@customers = mock([Customer]))
  end

  it "should retrieve a list of all customers" do
    get :index
    response.should be_success
    Customer.should_receive(:active_customers).and_return(@customers)
  end
end

これは機能せず、失敗しています。顧客はactive_customersを期待しているが、0回受け取ったと言っています。 Indexアクションの実際のコントローラーには、 @customers = Customer.active_customers があります。これを機能させるために何が欠けていますか?悲しいことに、RSpecに自分がやりたいことを伝える方法ではなく、仕様が何を説明しているのかを知っているので、テスト/仕様を考えてそれを書くよりも、コードを書く方が簡単であることがわかりました。

役に立ちましたか?

解決

スタブおよびメッセージの予想。メッセージの期待値は基本的にスタブであり、必要な定型応答を設定できますが、テスト対象のコードによって行われる呼び出しをテストします。対照的に、スタブはメソッド呼び出しに対する定型応答です。しかし、同じメソッドでスタブとメッセージ期待値を混在させてテストしないでください。悪いことが起こる ...

質問に戻りますが、ここで仕様を指定する必要があるのは2つ(またはそれ以上)です。

  1. index get を実行すると、CustomersControllerが Customer#active_customers を呼び出すこと。この仕様で Customer#active_customers が何を返すかは、実際には関係ありません。
  2. active_customers named_scopeは、実際には active フィールドが true である顧客を返します。

番号1を実行しようとしていると思います。その場合、スタブ全体を削除し、テストでメッセージの期待値を設定します。

describe CustomersController do
  it "should be successful and call Customer#active_customers" do
    Customer.should_receive(:active_customers)
    get :index
    response.should be_success
  end
end

上記の仕様では、返されるものをテストしていません。それは仕様の意図であるため、問題ありません(ただし、仕様は動作とは対照的に実装に近すぎますが、それは別のトピックです)。 active_customers への呼び出しで特に何かを返す場合は、先に進み、そのメッセージの期待値に .and_returns(@whatever)を追加します。ストーリーの他の部分は、 active_customers が期待どおりに動作することをテストすることです(つまり、実際にDBを呼び出すモデル仕様)。

他のヒント

次のように顧客レコードの配列を受け取ることをテストする場合は、モックの周りに配列があるはずです。

Customer.stub_chain(:active_customers).and_return(@customers = [mock(Customer)])

stub_chainは私にとって最適な方法です。

コントローラーを呼び出しています

ExerciseLog.this_user(current_user).past.all

このようにスタブすることができます

ExerciseLog.stub_chain(:this_user,:past).and_return(@exercise_logs = [mock(ExerciseLog),mock(ExerciseLog)])
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top