これは、Rspec book (page 149) から抜粋した、Rspec でヘルパー メソッドを作成する方法の説明です。この例では、「モノ」オブジェクトが作成されたときにトリガーされる「set_status」というメソッドがあることを前提としています。
どちらのコード セットも、新しい「モノ」オブジェクトを作成し、ステータスを設定してから、「fancy_stuff」を実行します。最初のコード セットは、私には完全に明確です。それがトリガーした「it」ステートメントの 1 つ。その後、オプションを指定して「create_thing」メソッドを呼び出します。新しい「モノ」オブジェクトが作成され、「オプション」属性をパラメータとして「set_status」メソッドが呼び出されます。
2 番目のコード セットも同様です。「it」ステートメントの 1 つがトリガーされ、「:status」ハッシュ割り当てをパラメーターとして渡しながら「given_thing_with」メソッドを呼び出します。「given_thing_with」メソッド内で、「Thing.new」をパラメータとして「yield」がトリガーされます。これは私が問題を抱えているところです。このコードを実行しようとすると、「block given to yield」というエラーが表示されます。「given_thing_with」メソッドを呼び出した「it」ステートメントから、yield によって渡されるすべての属性がパイプ ブレース内の「thing」に返されることを理解しています。新しいものを手に入れることができます
私が理解していないのは、「yield」コマンドの後に「given_thing_with」メソッドでコード ブロックが呼び出されない理由です。つまり、そのブロックでコードを実行することはできません。
よろしくお願いします。
この質問の残りの部分は、Rspec の本から直接引用されています。
describe Thing do
def create_thing(options)
thing = Thing.new
thing.set_status(options[:status])
thing
end
it "should do something when ok" do
thing = create_thing(:status => 'ok')
thing.do_fancy_stuff(1, true, :move => 'left', :obstacles => nil)
...
end
it "should do something else when not so good" do
thing = create_thing(:status => 'not so good')
thing.do_fancy_stuff(1, true, :move => 'left', :obstacles => nil)
...
end
end
これをさらにクリーンアップするために適用できるイディオムの 1 つは、オブジェクトの初期化子から self を生成することです。Thing の initialize() メソッドがこれを行い、set_status() も同様に行うと仮定すると、前のものは次のように記述できます。
describe Thing do
def given_thing_with(options)
yield Thing.new do |thing|
thing.set_status(options[:status])
end
end
it "should do something when ok" do
given_thing_with(:status => 'ok') do |thing|
thing.do_fancy_stuff(1, true, :move => 'left', :obstacles => nil)
...
end
end
it "should do something else when not so good" do
given_thing_with(:status => 'not so good') do |thing|
thing.do_fancy_stuff(1, true, :move => 'left', :obstacles => nil)
...
end
end
end