Remove `expect(…).to receive(…).with do...end` syntax
Created by: yujinakayama
Currently MessageExpectation#with
supports the following syntax:
it 'receives #some_method with 1' do
subject.should_receive(:some_method).with do |arg|
arg == 1
end
subject.some_method(1)
end
This syntax allows you to expect arbitrary arguments without expect
or should
by using the return value of the block passed to #with
. This is available only when #with
got no normal arguments but a block, and the block will not be used as a substitute implementation.
- https://github.com/rspec/rspec-mocks/blob/e6d1980/lib/rspec/mocks/message_expectation.rb#L307
- https://github.com/rspec/rspec-mocks/blob/e6d1980/lib/rspec/mocks/argument_list_matcher.rb#L43
Then, if you convert the example into expect
syntax straightforward:
it 'receives #some_method with 1' do
expect(subject).to receive(:some_method).with do |arg|
arg == 1
end
subject.some_method(1)
end
and run:
Failures:
1) the issue with `expect(subject).to receive(:some_method).with do ... end` with #expect receives #some_method with 1
Failure/Error: subject.some_method(1)
Double "subject" received :some_method with unexpected arguments
expected: (no args)
got: (1)
This is caused by the lower precedence of do..end
blocks. If you use {..}
style block, it works. Basically this is similar to this one:
https://github.com/rspec/rspec-expectations/pull/295
I guess there's a way to handle this issue technically, though it would probably make MessageExpectation
complex.
Rather, I'd like to suggest deprecating this feature. I think most users don't even know this exists and there's a reasonable alternative way. You can simply use expect
in substitute implementation blocks like the example in README.
In fact I didn't know this feature too. I've found this in Guard's spec while testing my should
to expect
converter, though the spec seems to be using the feature unintentionally.
What do you think?
Reproducible example: https://gist.github.com/yujinakayama/6063761