Reputation: 4492
i am trying to use and_yield
the same way that and_return
works. i want it to yield ONE value each time its called... however it yields TWICE each time its called.
this contrived example shows the issue
class Yielder
@@blocks = []
def self.yielder; end
def self.blocks= b; @@blocks << b; end
def self.blocks; @@blocks; end
end
describe Yielder do
it 'should yield twice' do
allow(Yielder).to receive(:yielder).and_yield(:foo).and_yield(:bar)
2.times do
Yielder.yielder do |y|
Yielder.blocks = y
end
end
expect(Yielder).to have_received(:yielder).twice
expect(Yielder.blocks).to eq [:foo, :bar]
end
end
rspec results...
expected: [:foo, :bar]
got: [:foo, :bar, :foo, :bar]
am i using this incorrectly?
Upvotes: 3
Views: 641
Reputation: 508
As suggested, and_yield
doesn't work the same way and_return
does. But if you want that kind of behavior, you could do the following:
describe Yielder do
it 'should yield twice' do
values = [:foo, :bar]
allow(Yielder).to receive(:yielder) do |&block|
block.call(values.shift)
end
2.times do
Yielder.yielder do |y|
Yielder.blocks = y
end
end
expect(Yielder).to have_received(:yielder).twice
expect(Yielder.blocks).to eq [:foo, :bar]
end
end
Upvotes: 4