-
-
Notifications
You must be signed in to change notification settings - Fork 358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider deprecating and_return { value }
#558
Comments
I think it would be good to deprecate |
OK, I'll try. |
I've noticed it's more problematic than I thought. It behaves unexpectedly with describe '`and_return` without arguments' do
let(:obj) { double('obj') }
context 'with `stub`' do
context 'and `{ }` block' do
it 'works properly' do
obj.stub(:foo).and_return {
'a return value'
}
expect(obj.foo).to eq('a return value')
end
end
context 'and `do end` block' do
it 'works properly' do
obj.stub(:foo).and_return do
'a return value'
end
expect(obj.foo).to eq('a return value')
end
end
end
context 'with `allow(...).to receive(...)`' do
context 'and `{ }` block' do
it 'works properly' do
# The block is taken by #and_return.
allow(obj).to receive(:foo).and_return {
'a return value'
}
expect(obj.foo).to eq('a return value')
end
end
context 'and `do end` block' do
it 'returns nil unexpectedly' do
# The block is taken by #to.
allow(obj).to receive(:foo).and_return do
'a return value'
end
# Describing the unexpected behavior,
# this should not pass, but passes.
expect(obj.foo).to be_nil
end
end
end
context 'without block' do
it 'returns nil' do
# Shouldn't this raise error?
allow(obj).to receive(:foo).and_return
expect(obj.foo).to be_nil
end
end
end This is because:
So, I think we should probably disallow the Thoughts? The spec gist: https://gist.github.com/yujinakayama/8847524 |
For the
I agree. def and_return(first_return, *values)
values.unshift(first_return)
# ...
end ...rather than: def and_return(*values)
# ...
end Then ruby itself will provide an appropriate |
OK. I'll handle it also.
Sorry, I've tested only on |
If it was a regression in 2.14 or 2.99, then definitely. However, given that the If there's demand from users I'll backport it but there hasn't been. |
Curious why and_return was deprecated... To my eyes: expect(controller).to receive(:send_file).once.and_return { controller.render :nothing => true } is more readable than: expect(controller).to receive(:send_file).once { controller.render :nothing => true } That second one seems harder to figure out, like a paragraph that's missing punctuation. |
What's been deprecated is passing only a block to |
That's what I meant. :) The example is only passing a block. Is there a more readable way of writing this that complies with the deprecation? |
The problem is that the block can do literally anything. It's not just for returning values. It can perform any side effect, throw a symbol, raise an error or do whatever. As such, using expect(controller).to receive(:send_file).once.and_return(controller.render :nothing => true) |
|
@myronmarston, in this case, 'literally everything' is the behavior I like. :) Calling @JonRowe thanks for confirming that this is as readable as it gets. It doesn't seem particularly friendly to people less familiar with rspec (to me) but that's OK. Thank you to you both for taking your time to explain this. It will work fine. |
|
Well that's a flippin' good point. expect(controller).to receive(:send_file).and_also_call { controller.render :nothing => true } |
I've found a comment “TODO: deprecate
and_return { value }
” here. Should this be removed in RSpec 3?Actually I think this is not so problematic in comparison to the issue in
with { ... }
, so I won't insist (and I don't want to have more work on Transpec 😁).What do you think?
The text was updated successfully, but these errors were encountered: