メインコンテンツまでスキップ

ユーザー定義の引数を返す

and_yield を使用して、テストダブルがメッセージを受け取ったときに提供された引数を返すようにします。呼び出し元がブロックを提供しない場合、または呼び出し元のブロックが提供された引数を受け入れない場合、エラーが発生します。複数回返す場合は、複数の and_yield 呼び出しを連結します。

引数を返す

次の内容で "yield_arguments_spec.rb" という名前のファイルを作成します。

RSpec.describe "Making it yield arguments" do
it "yields the provided args" do
dbl = double
allow(dbl).to receive(:foo).and_yield(2, 3)

x = y = nil
dbl.foo { |a, b| x, y = a, b }
expect(x).to eq(2)
expect(y).to eq(3)
end
end

rspec yield_arguments_spec.rb を実行すると、

すべての例がパスするはずです。

呼び出し元がブロックを提供しない場合は失敗する

次の内容で "no_caller_block_spec.rb" という名前のファイルを作成します。

RSpec.describe "Making it yield" do
it "fails when the caller does not provide a block" do
dbl = double
allow(dbl).to receive(:foo).and_yield(2, 3)
dbl.foo
end
end

rspec no_caller_block_spec.rb を実行すると、

次のエラーが発生するはずです。

#<Double (anonymous)> asked to yield |[2, 3]| but no block was passed

呼び出し元のブロックが提供された引数を受け入れない場合は失敗する

次の内容で "arg_mismatch_spec.rb" という名前のファイルを作成します。

RSpec.describe "Making it yield" do
it "fails when the caller's block does not accept the provided arguments" do
dbl = double
allow(dbl).to receive(:foo).and_yield(2, 3)
dbl.foo { |x| }
end
end

rspec arg_mismatch_spec.rb を実行すると、

次のエラーが発生するはずです。

#<Double (anonymous)> yielded |2, 3| to block with arity of 1

複数回返す

次の内容で "yield_multiple_times_spec.rb" という名前のファイルを作成します。

RSpec.describe "Making it yield multiple times" do
it "yields the specified args in succession" do
yielded = []

dbl = double
allow(dbl).to receive(:foo).and_yield(1).and_yield(2).and_yield(3)
dbl.foo { |x| yielded << x }

expect(yielded).to eq([1, 2, 3])
end
end

rspec yield_multiple_times_spec.rb を実行すると、

すべての例がパスするはずです。