RSpec and blocks
How to test this with RSpec?
module Thing def self.call Foo.call do Bar.call end yield end end
Foo.call, in order for block that contains
Bar.call to be
called, we need to use
and_yield. It can take arguments. See also
RSpec.describe Thing do before do allow(Foo).to receive(:call).and_yield allow(Bar).to receive(:call) end describe '.call' do it 'calls Foo' do described_class.call expect(Foo).to have_received(:call) end it 'calls Bar' do described_class.call expect(Bar).to have_received(:call) end end end
We can expect the subject under test to yield control by passing a block to
expect with an argument. The argument itself is a block, captured (
passed to the method call. See also https://relishapp.com/rspec/rspec-expectations/v/3-11/docs/built-in-matchers/yield-matchers
it 'yields control to a block' do expect do |b| described_class.call(&b) end.to yield_control end
# Other RSpecy things
This isn’t related to block testing, but putting this here for now.
Can be used to stub multiple calls to the same method, which could raise and retry see also https://www.rubydoc.info/github/rspec/rspec-mocks/RSpec%2FMocks%2FMessageExpectation:and_invoke