@private When we mock or stub a method on a class, we have to treat it a bit different, because normally singleton method definitions only affect the object on which they are defined, but on classes they affect subclasses, too. As a result, we need some special handling to get the original method.
Consider this situation:
class A; end class B < A; end allow(A).to receive(:new) expect(B).to receive(:new).and_call_original
When getting the original definition for `B.new`, we cannot rely purely on using `B.method(:new)` before our redefinition is defined on `B`, because `B.method(:new)` will return a method that will execute the stubbed version of the method on `A` since singleton methods on classes are in the lookup hierarchy.
To do it properly, we need to find the original definition of `new` from `A` from before `A` was stubbed, and we need to rebind it to `B` so that it will run with the proper `self`.
That’s what this method (together with `original_unbound_method_handle_from_ancestor_for`) does.
# File lib/rspec/mocks/proxy.rb, line 353 def original_method_handle_for(message) unbound_method = superclass_proxy && superclass_proxy.original_unbound_method_handle_from_ancestor_for(message.to_sym) return super unless unbound_method unbound_method.bind(object) end
# File lib/rspec/mocks/proxy.rb, line 363 def original_unbound_method_handle_from_ancestor_for(message) method_double = @method_doubles.fetch(message) do # The fact that there is no method double for this message indicates # that it has not been redefined by rspec-mocks. We need to continue # looking up the ancestor chain. return superclass_proxy && superclass_proxy.original_unbound_method_handle_from_ancestor_for(message) end method_double.original_method.unbind end
Generated with the Darkfish Rdoc Generator 2.