web-dev-qa-db-ja.com

RSpec:引数付きのスタブチェーン?

Rspecスタブチェーンで引数を渡すことができるかどうか/どのようにできるか疑問に思っています。例を挙げると、次のアクションがあるとします。

def index
  @payments = Payment.order(:updated_at).where(:paid => true)
  @bad_payments = Payment.order(:some_other_field).where(:paid => false)
end

私のコントローラー仕様では、両方のメソッドをスタブ化して異なる結果を返すことができるようにしたいと思います。 @paymentsフィールドのみがアクションに含まれている場合は、次のようなものを使用します。

Payment.stub_chain(:order, :where) { return_this }

しかしもちろん、それは@bad_paymentsに同じ値を返します。

つまり、スタブ条件とし​​て:updated_at:paid => trueを含めるにはどうすればよいですか?

31
PlankTon

あなたはこれを使うことができます:

Payment.stub_chain(:order, :where).with(:updated_at).with(:paid => true) { return_this }
23
Elad Maimon

rspec > 3次の構文を使用します:

expect(Converter).to receive_message_chain("new.update_value").with('test').with(no_args)

の代わりに stub_chain

メッセージチェーンの詳細を読む ドキュメント内 。そして ここ は引数マッチャーのドキュメントです。

16
czerasz

ネストされたスタブブロックを使用できます。ブロックは引数を受け入れることができ、戻り値は関数の戻り値として使用されます。

tapは呼び出し先を返さないため、stubを使用します。 doubleによって作成されたmockは、メソッドorderの結果として返されます。このメソッドは、whereメソッドが再びスタブになります。

Payment.stub(:order) { |order|
  double('ordered_payments').tap { |proxy|
    proxy.stub(:where) { |where|
      [order, where]
    }
  }
}

Payment.order(:updated_at).where(:paid => true)
# => returns [:updated_at, {:paid => true}]
15
Ian Yang