Module: RSpec::Mocks::PartialClassDoubleProxyMethods

Included in:
PartialClassDoubleProxy, VerifyingPartialClassDoubleProxy
Defined in:
lib/rspec/mocks/proxy.rb

Overview

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.

Instance Method Summary (collapse)

Instance Method Details

- (Object) initialize(source_space, *args)



312
313
314
315
# File 'lib/rspec/mocks/proxy.rb', line 312

def initialize(source_space, *args)
  @source_space = source_space
  super(*args)
end

- (Object) original_method_handle_for(message)

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.



337
338
339
340
341
342
343
# File 'lib/rspec/mocks/proxy.rb', line 337

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