-
-
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
Prevent mocks leaking out of their scope when mocked more than once in different nested scopes. #1424
Comments
Looks reasonable. Would you like to hack on this? Wondering how do you use nested spaces in your specs, can you give a hint? |
I'll maybe try to write a fix, but it could take a while. If someone else wants to do it earlier I'ld be totally fine with it. Regarding the usage: I have a class that is instantiated with some well-defined arguments and the initializer also conditionally calls a method (let's call it Something like this (very much simplified): class A
def initialize(*args)
if some_condition
@test = C.rnd_method
end
...
end
end
RSpec.describe A do
before(:each) do
allow(A).to receive(:new).and_wrap_original do |method, *args|
RSpec::Mocks.with_temporary_scope do
allow(C).to receive(:rnd_method).once.and_return(5)
method.call(*args)
end
end
end
it 'works' do
expect(C).to receive(:rnd_method).twice.and_return(2)
some_method_that_calls_A_new_and_C_rnd_method
end
end I suppose that, even though this is a simplified version, the real code could be optimized to not need the temporary scope. |
I have some different problem with nested scopes. Maybe it is related… The next code produces unexpected results for nested scopes: class Keys
def Keys.private_key = '0'
end
RSpec.describe 'cases' do
it 'not nested mock' do
puts Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('1')
puts ' '+Keys.private_key
end
puts Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('2')
puts '' + Keys.private_key
end
puts Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('3')
puts ' '+Keys.private_key
end
puts Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('4')
puts ' '+Keys.private_key
end
puts Keys.private_key
end
it 'nested mock' do
puts Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('1')
puts ' '+Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('2')
puts ' '+Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('3')
puts ' '+Keys.private_key
RSpec::Mocks.with_temporary_scope do
allow(Keys).to receive(:private_key).and_return('4')
puts ' '+Keys.private_key
end
puts ' '+Keys.private_key
end
puts ' '+Keys.private_key
end
puts ' '+Keys.private_key
end
puts Keys.private_key
end
end Results:
|
Subject of the issue
When mocking a method in an outer and inner scope using combinations of
expect
andallow
, the mocks leak out of the inner scope. I suppose that this is a bug because it only happens when the method was first mocked in the outer scope.If it is a feature it is a pretty unintuitive one.
Your environment
Steps to reproduce
Expected behavior
All tests should pass.
Actual behavior
The text was updated successfully, but these errors were encountered: