Skip to content
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

Mark any_instance proxy methods as private if they were private #1596

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/rspec/mocks/any_instance/recorder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,12 @@ def observe!(method_name)
@observed_methods << method_name
backup_method!(method_name)
recorder = self
method_was_private = @klass.private_method_defined?(method_name)
@klass.__send__(:define_method, method_name) do |*args, &blk|
recorder.playback!(self, method_name)
__send__(method_name, *args, &blk)
end
@klass.__send__(:private, method_name) if method_was_private
@klass.__send__(:ruby2_keywords, method_name) if @klass.respond_to?(:ruby2_keywords, true)
end

Expand Down
40 changes: 31 additions & 9 deletions spec/rspec/mocks/any_instance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1074,22 +1074,43 @@ def foo; end
end

context "private methods" do
before :each do
allow_any_instance_of(klass).to receive(:private_method).and_return(:something)
before(:example) { allow_any_instance_of(klass).to receive(:private_method).and_return(:something) }

verify_all
let(:object) { klass.new }

# The map(&:to_sym) is for legacy Ruby compatability and can be dropped in RSpec 4
it "maintains the method in the list of private_methods" do
expect {
verify_all
}.to_not change { object.private_methods.map(&:to_sym).include?(:private_method) }.from(true)
end

it "cleans up the backed up method" do
expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
it "maintains the methods exclusion from the list of public_methods" do
expect {
verify_all
}.to_not change { object.public_methods.map(&:to_sym).include?(:private_method) }.from(false)
end

it "restores a stubbed private method after the spec is run" do
it "maintains the methods visibility" do
expect { klass.new.private_method }.to raise_error(NoMethodError)
expect(klass.new.send(:private_method)).to eq(:something)
expect(klass.private_method_defined?(:private_method)).to be_truthy
end

it "ensures that the restored method behaves as it originally did" do
expect(klass.new.send(:private_method)).to eq(:private_method_return_value)
context "after the spec has run" do
before(:example) { verify_all }

it "cleans up the backed up method" do
expect(klass.method_defined?(:__existing_method_without_any_instance__)).to be_falsey
end

it "restores a stubbed private method after the spec is run" do
expect(klass.private_method_defined?(:private_method)).to be_truthy
end

it "ensures that the restored method behaves as it originally did" do
expect(klass.new.send(:private_method)).to eq(:private_method_return_value)
end
end
end
end
Expand All @@ -1098,7 +1119,7 @@ def foo; end
context "private methods" do
before :each do
expect_any_instance_of(klass).to receive(:private_method).and_return(:something)
klass.new.private_method
klass.new.send(:private_method)

verify_all
end
Expand All @@ -1109,6 +1130,7 @@ def foo; end

it "restores a stubbed private method after the spec is run" do
expect(klass.private_method_defined?(:private_method)).to be_truthy
expect(klass.new.private_methods.map(&:to_sym)).to include :private_method
end

it "ensures that the restored method behaves as it originally did" do
Expand Down
Loading