2

私は Michael Hartl の Rails Tutorial に従っており、RSpec テスト コード スニペットがあります。

expect do
 click_button 'Follow'
end.to change(user.followed_users, :count).by(1)`

RSpec のドキュメントとCodeschoolで学んだ方法によると、これは実際には次のようになります。

expect do
 click_button 'Follow'
end.to change {user.followed_users.count}.by(1)

明らかにどちらも有効ですが、RSpec ドキュメントで変更マッチャーを実行する最初の方法についてのドキュメントはないようで、なぜ/どのように機能するのか疑問に思っています。

4

2 に答える 2

4

Relish のドキュメントにも見つかりませんでしたが、RSpec は結局オープン ソースなので、掘り下げてみましょう。変更マッチャーの現在のバージョンでは、次のようになります。

module RSpec
  module Matchers
    module BuiltIn
      class Change
        def initialize(receiver=nil, message=nil, &block)
          @message = message
          @value_proc = block || lambda {receiver.__send__(message)}
          @expected_after = @expected_before = @minimum = @maximum = @expected_delta = nil
          @eval_before = @eval_after = false
        end

それはすべてについて@value_procです。ブロックを指定すると、それが使用されます。ブロックを指定しない場合は、2 番目の引数を最初の引数に送信する新しいラムダが作成されます。ソースをもう少し読むと#matches?、以下を含むメソッドが表示されます。

@actual_before = evaluate_value_proc
event_proc.call
@actual_after = evaluate_value_proc

evaluate_value_proc主にどこにし@value_proc.callますか?

「従来の」RSpecでは、明示的なブロックを提供する必要があると思います。メタプログラミングをしている場合は、2 つの引数を使用するアプローチの方が理にかなっているかもしれませんが、その場合でも、ブロック アプローチを使用して自分自身を呼び出すことができsendます。

于 2013-05-14T14:43:50.433 に答える