rspec-mocks
rspec-mocks copied to clipboard
stub_const does not restore Object.const_source_location after reset
Subject of the issue
When using stub_const
, it does not reset Object.const_source_location
after example finished.
Your environment
- Ruby version: 2.7.5, 3.2.2
- rspec-mocks version: 3.12.6
Steps to reproduce
File: spec/foo_spec.rb
class Foo; end
RSpec.describe Foo do
it 'stubs and can be reset' do
stub_const('Foo', Class.new)
expect(Object.const_source_location('Foo').first).not_to include('foo_spec.rb')
RSpec::Mocks.space.reset_all
expect(Object.const_source_location('Foo').first).to include('foo_spec.rb')
end
end
Expected behavior
Expect above test to pass.
Actual behavior
Foo
stubs and can be reset (FAILED - 1)
Failures:
1) Foo stubs and can be reset
Failure/Error: expect(Object.const_source_location('Foo').first).to include('foo_spec.rb')
expected "/Users/wei-fun.chang/workspace/rspec-mocks/lib/rspec/mocks/mutate_const.rb" to include "foo_spec.rb"
...
Would it reproduce if you’d put the class definition with the production code?
What is your use case?
Would it reproduce if you’d put the class definition with the production code?
I am not exactly sure the "production code" means here. Basically the const_set
in reset will always set the source location to where it was called: https://github.com/rspec/rspec-mocks/blob/main/lib/rspec/mocks/mutate_const.rb#L229
Not an expert of C but I think it's defined here: https://github.com/ruby/ruby/blob/b1f0d009cbdf1990813c09165d372be29485f8ae/variable.c#L3482
What is your use case?
We have a code owner trace lib based on Object.const_source_location
to map the code owner through the file path where the original class was defined. Recently there is a test flake caused by not able to pin down the owner because of source location changed to rspec-mock
.
I'm not sure theres much we can do about that, given that the location of this is set by Ruby, we don't really have an alternate way to set constants that I know of, I would suggest you need to rework your tests to avoid using stub_const
(or stub out const_source_location to remove the mock locations) sorry 😞
Closing during the monorepo migration, because I don't think there is anything we can do, but if someone finds a way to reasonably improve this please do reopen there.