Skip to content

Commit

Permalink
any_instance is supported when a class overrides Object#method
Browse files Browse the repository at this point in the history
* Fixes #180
* Closes #181
  • Loading branch information
alindeman committed Aug 26, 2012
1 parent 3e3e64d commit 645b158
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Bug fixes

* Fix `:transfer_nested_constants` option of `stub_const` so that it
doesn't blow up when there are inherited constants. (Myron Marston)
* `any_instance` stubs can be used on classes that override `Object#method`.
(Andy Lindeman)

Deprecations:

Expand Down
4 changes: 2 additions & 2 deletions lib/rspec/mocks/any_instance/recorder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def observe!(method_name)
backup_method!(method_name)
@klass.class_eval(<<-EOM, __FILE__, __LINE__)
def #{method_name}(*args, &blk)
klass = self.method(:#{method_name}).owner
klass = ::Object.instance_method(:method).bind(self).call(:#{method_name}).owner
klass.__recorder.playback!(self, :#{method_name})
self.__send__(:#{method_name}, *args, &blk)
end
Expand All @@ -187,7 +187,7 @@ def mark_invoked!(method_name)
@klass.class_eval(<<-EOM, __FILE__, __LINE__)
def #{method_name}(*args, &blk)
method_name = :#{method_name}
klass = self.method(:#{method_name}).owner
klass = ::Object.instance_method(:method).bind(self).call(:#{method_name}).owner
invoked_instance = klass.__recorder.instance_that_received(method_name)
raise RSpec::Mocks::MockExpectationError, "The message '#{method_name}' was received by \#{self.inspect} but has already been received by \#{invoked_instance}"
end
Expand Down
14 changes: 14 additions & 0 deletions spec/rspec/mocks/any_instance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,20 @@ class RSpec::SampleRspecTestClass;end
end.to raise_error(RSpec::Mocks::MockExpectationError, "The message 'existing_method' was received by #{instance_two.inspect} but has already been received by #{instance_one.inspect}")
end
end

context "when a class overrides Object#method" do
let(:http_request_class) { Struct.new(:method, :uri) }

it "stubs the method correctly" do
http_request_class.any_instance.stub(:existing_method).and_return("foo")
http_request_class.new.existing_method.should == "foo"
end

it "mocks the method correctly" do
http_request_class.any_instance.should_receive(:existing_method).and_return("foo")
http_request_class.new.existing_method.should == "foo"
end
end
end
end
end

0 comments on commit 645b158

Please sign in to comment.