Skip to content
Browse files

Bug fix: any_instance now properly restores private methods

- Closes #86.
- Fixes #85.
  • Loading branch information...
1 parent f0f9d4a commit 5b862e6fad8621c48f0db02b8791b053a4924de2 @kaiwren kaiwren committed with dchelimsky Oct 15, 2011
Showing with 73 additions and 28 deletions.
  1. +8 −6 lib/rspec/mocks/any_instance/recorder.rb
  2. +65 −22 spec/rspec/mocks/any_instance_spec.rb
View
14 lib/rspec/mocks/any_instance/recorder.rb
@@ -93,7 +93,7 @@ def received_expected_message!(method_name)
end
def restore_method!(method_name)
- if @klass.method_defined?(build_alias_method_name(method_name))
+ if public_protected_or_private_method_defined?(build_alias_method_name(method_name))
restore_original_method!(method_name)
else
remove_dummy_method!(method_name)
@@ -122,12 +122,14 @@ def remove_dummy_method!(method_name)
def backup_method!(method_name)
alias_method_name = build_alias_method_name(method_name)
@klass.class_eval do
- if method_defined?(method_name)
- alias_method alias_method_name, method_name
- end
- end
+ alias_method alias_method_name, method_name
+ end if public_protected_or_private_method_defined?(method_name)
end
-
+
+ def public_protected_or_private_method_defined?(method_name)
+ @klass.method_defined?(method_name) || @klass.private_method_defined?(method_name)
+ end
+
def stop_observing!(method_name)
restore_method!(method_name)
@observed_methods.delete(method_name)
View
87 spec/rspec/mocks/any_instance_spec.rb
@@ -10,6 +10,8 @@ class CustomErrorForAnyInstanceSpec < StandardError;end
def existing_method; :existing_method_return_value; end
def existing_method_with_arguments(arg_one, arg_two = nil); :existing_method_with_arguments_return_value; end
def another_existing_method; end
+ private
+ def private_method; :private_method_return_value; end
end
end
let(:existing_method_return_value){ :existing_method_return_value }
@@ -194,7 +196,7 @@ def another_existing_method; end
klass.new.foo.should eq(klass.new.foo)
end
end
-
+
context "core ruby objects" do
it "works uniformly across *everything*" do
Object.any_instance.stub(:foo).and_return(1)
@@ -642,39 +644,80 @@ class RSpec::SampleRspecTestClass;end
end
context "with stubbing" do
- before(:each) do
- klass.any_instance.stub(:existing_method).and_return(1)
- klass.method_defined?(:__existing_method_without_any_instance__).should be_true
- end
+ context "public methods" do
+ before(:each) do
+ klass.any_instance.stub(:existing_method).and_return(1)
+ klass.method_defined?(:__existing_method_without_any_instance__).should be_true
+ end
- it "restores the class to its original state after each example when no instance is created" do
- space.verify_all
+ it "restores the class to its original state after each example when no instance is created" do
+ space.verify_all
- klass.method_defined?(:__existing_method_without_any_instance__).should be_false
- klass.new.existing_method.should eq(existing_method_return_value)
- end
+ klass.method_defined?(:__existing_method_without_any_instance__).should be_false
+ klass.new.existing_method.should eq(existing_method_return_value)
+ end
- it "restores the class to its original state after each example when one instance is created" do
- klass.new.existing_method
+ it "restores the class to its original state after each example when one instance is created" do
+ klass.new.existing_method
- space.verify_all
+ space.verify_all
- klass.method_defined?(:__existing_method_without_any_instance__).should be_false
- klass.new.existing_method.should eq(existing_method_return_value)
- end
+ klass.method_defined?(:__existing_method_without_any_instance__).should be_false
+ klass.new.existing_method.should eq(existing_method_return_value)
+ end
- it "restores the class to its original state after each example when more than one instance is created" do
- klass.new.existing_method
- klass.new.existing_method
+ it "restores the class to its original state after each example when more than one instance is created" do
+ klass.new.existing_method
+ klass.new.existing_method
- space.verify_all
+ space.verify_all
- klass.method_defined?(:__existing_method_without_any_instance__).should be_false
- klass.new.existing_method.should eq(existing_method_return_value)
+ klass.method_defined?(:__existing_method_without_any_instance__).should be_false
+ klass.new.existing_method.should eq(existing_method_return_value)
+ end
+ end
+
+ context "private methods" do
+ before :each do
+ klass.any_instance.stub(:private_method).and_return(:something)
+ space.verify_all
+ end
+
+ it "cleans up the backed up method" do
+ klass.method_defined?(:__existing_method_without_any_instance__).should be_false
+ end
+
+ it "restores a stubbed private method after the spec is run" do
+ klass.private_method_defined?(:private_method).should be_true
+ end
+
+ it "ensures that the restored method behaves as it originally did" do
+ klass.new.send(:private_method).should eq(:private_method_return_value)
+ end
end
end
context "with expectations" do
+ context "private methods" do
+ before :each do
+ klass.any_instance.should_receive(:private_method).and_return(:something)
+ klass.new.private_method
+ space.verify_all
+ end
+
+ it "cleans up the backed up method" do
+ klass.method_defined?(:__existing_method_without_any_instance__).should be_false
+ end
+
+ it "restores a stubbed private method after the spec is run" do
+ klass.private_method_defined?(:private_method).should be_true
+ end
+
+ it "ensures that the restored method behaves as it originally did" do
+ klass.new.send(:private_method).should eq(:private_method_return_value)
+ end
+ end
+
context "ensures that the subsequent specs do not see expectations set in previous specs" do
context "when the instance created after the expectation is set" do
it "first spec" do

0 comments on commit 5b862e6

Please sign in to comment.
Something went wrong with that request. Please try again.