Class: RSpec::Mocks::MethodDouble

### Home Classes Methods

### In Files

- lib/rspec/mocks/method_double.rb

### Parent

Object

### Methods

- ::new
- #add_default_stub
- #add_expectation
- #add_simple_expectation
- #add_simple_stub
- #add_stub
- #build_expectation
- #clear
- #configure_method
- #define_proxy_method
- #definition_target
- #message_expectation_class
- #new_rspec_prepended_module
- #object_singleton_class
- #original_method
- #proxy_method_invoked
- #raise_method_not_stubbed_error
- #remove_stub
- #remove_stub_if_present
- #reset
- #restore_original_method
- #restore_original_visibility
- #save_original_method!
- #setup_simple_method_double
- #show_frozen_warning
- #usable_rspec_prepended_module
- #verify
- #visibility

### Class/Module Index

Quicksearch

- RSpec
- RSpec::Mocks
- RSpec::Mocks::AllowanceTarget
- RSpec::Mocks::AndReturnImplementation
- RSpec::Mocks::AndWrapOriginalImplementation
- RSpec::Mocks::AndYieldImplementation
- RSpec::Mocks::AnyInstance
- RSpec::Mocks::AnyInstance::Chain
- RSpec::Mocks::AnyInstance::Chain::Customizations
- RSpec::Mocks::AnyInstance::ExpectChainChain
- RSpec::Mocks::AnyInstance::ExpectationChain
- RSpec::Mocks::AnyInstance::FluentInterfaceProxy
- RSpec::Mocks::AnyInstance::MessageChains
- RSpec::Mocks::AnyInstance::PositiveExpectationChain
- RSpec::Mocks::AnyInstance::Proxy
- RSpec::Mocks::AnyInstance::Recorder
- RSpec::Mocks::AnyInstance::StubChain
- RSpec::Mocks::AnyInstance::StubChainChain
- RSpec::Mocks::AnyInstanceAllowanceTarget
- RSpec::Mocks::AnyInstanceExpectationTarget
- RSpec::Mocks::ArgumentListMatcher
- RSpec::Mocks::ArgumentMatchers
- RSpec::Mocks::ArgumentMatchers::AnyArgMatcher
- RSpec::Mocks::ArgumentMatchers::AnyArgsMatcher
- RSpec::Mocks::ArgumentMatchers::ArrayIncludingMatcher
- RSpec::Mocks::ArgumentMatchers::BaseHashMatcher
- RSpec::Mocks::ArgumentMatchers::BooleanMatcher
- RSpec::Mocks::ArgumentMatchers::DuckTypeMatcher
- RSpec::Mocks::ArgumentMatchers::HashExcludingMatcher
- RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher
- RSpec::Mocks::ArgumentMatchers::InstanceOf
- RSpec::Mocks::ArgumentMatchers::KindOf
- RSpec::Mocks::ArgumentMatchers::NoArgsMatcher
- RSpec::Mocks::ArgumentMatchers::SingletonMatcher
- RSpec::Mocks::ClassVerifyingDouble
- RSpec::Mocks::Configuration
- RSpec::Mocks::Constant
- RSpec::Mocks::ConstantMutator
- RSpec::Mocks::ConstantMutator::BaseMutator
- RSpec::Mocks::ConstantMutator::ConstantHider
- RSpec::Mocks::ConstantMutator::DefinedConstantReplacer
- RSpec::Mocks::ConstantMutator::UndefinedConstantSetter
- RSpec::Mocks::DirectObjectReference
- RSpec::Mocks::Double
- RSpec::Mocks::ErrorGenerator
- RSpec::Mocks::ExampleMethods
- RSpec::Mocks::ExampleMethods::ExpectHost
- RSpec::Mocks::ExpectChain
- RSpec::Mocks::ExpectationTarget
- RSpec::Mocks::Implementation
- RSpec::Mocks::InsertOntoBacktrace
- RSpec::Mocks::InstanceMethodReference
- RSpec::Mocks::InstanceMethodStasher
- RSpec::Mocks::InstanceVerifyingDouble
- RSpec::Mocks::MarshalExtension
- RSpec::Mocks::Matchers
- RSpec::Mocks::Matchers::ExpectationCustomization
- RSpec::Mocks::Matchers::HaveReceived
- RSpec::Mocks::Matchers::Receive
- RSpec::Mocks::Matchers::Receive::DefaultDescribable
- RSpec::Mocks::Matchers::ReceiveMessageChain
- RSpec::Mocks::Matchers::ReceiveMessages
- RSpec::Mocks::MessageChain
- RSpec::Mocks::MessageExpectation
- RSpec::Mocks::MessageExpectation::ImplementationDetails
- RSpec::Mocks::MethodDouble
- RSpec::Mocks::MethodReference
- RSpec::Mocks::NamedObjectReference
- RSpec::Mocks::NestedSpace
- RSpec::Mocks::ObjectMethodReference
- RSpec::Mocks::ObjectReference
- RSpec::Mocks::ObjectVerifyingDouble
- RSpec::Mocks::ObjectVerifyingDoubleMethods
- RSpec::Mocks::OrderGroup
- RSpec::Mocks::PartialClassDoubleProxy
- RSpec::Mocks::PartialClassDoubleProxyMethods
- RSpec::Mocks::PartialDoubleProxy
- RSpec::Mocks::Proxy
- RSpec::Mocks::ProxyForNil
- RSpec::Mocks::RootSpace
- RSpec::Mocks::SimpleMessageExpectation
- RSpec::Mocks::Space
- RSpec::Mocks::Space::FakeMutex
- RSpec::Mocks::StubChain
- RSpec::Mocks::Syntax
- RSpec::Mocks::TargetBase
- RSpec::Mocks::TestDouble
- RSpec::Mocks::TestDoubleProxy
- RSpec::Mocks::VerifyingDouble
- RSpec::Mocks::VerifyingExistingMethodDouble
- RSpec::Mocks::VerifyingMessageExpectation
- RSpec::Mocks::VerifyingMethodDouble
- RSpec::Mocks::VerifyingPartialClassDoubleProxy
- RSpec::Mocks::VerifyingPartialDoubleProxy
- RSpec::Mocks::VerifyingProxy
- RSpec::Mocks::VerifyingProxyMethods
- RSpec::Mocks::Version
- BasicObject
- Class

No matching classes.

# RSpec::Mocks::MethodDouble

@private

### Constants

RSpecPrependedModule

  We subclass `Module` in order to be able to easily detect our prepended module.

### Attributes

expectations[R]

@private

method_name[R]

@private

object[R]

@private

stubs[R]

@private

### Public Class Methods

new(object, method_name, proxy) click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 9
    def initialize(object, method_name, proxy)
      @method_name = method_name
      @object = object
      @proxy = proxy

      @original_visibility = nil
      @method_stasher = InstanceMethodStasher.new(object, method_name)
      @method_is_proxied = false
      @expectations = []
      @stubs = []
    end

### Public Instance Methods

add_default_stub(*args, &implementation) click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 183
    def add_default_stub(*args, &implementation)
      return if stubs.any?
      add_stub(*args, &implementation)
    end

add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation) click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 133
    def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation)
      configure_method
      expectation = message_expectation_class.new(error_generator, expectation_ordering,
                                                  expected_from, self, :expectation, opts, &implementation)
      expectations << expectation
      expectation
    end

add_simple_expectation(method_name, response, error_generator, backtrace_line) click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 169
    def add_simple_expectation(method_name, response, error_generator, backtrace_line)
      setup_simple_method_double method_name, response, expectations, error_generator, backtrace_line
    end

add_simple_stub(method_name, response) click to toggle source

A simple stub can only return a concrete value for a message, and cannot match on arguments. It is used as an optimization over `add_stub` / `add_expectation` where it is known in advance that this is all that will be required of a stub, such as when passing attributes to the `double` example method. They do not stash or restore existing method definitions.

@private

    # File lib/rspec/mocks/method_double.rb, line 164
    def add_simple_stub(method_name, response)
      setup_simple_method_double method_name, response, stubs
    end

add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation) click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 148
    def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation)
      configure_method
      stub = message_expectation_class.new(error_generator, expectation_ordering, expected_from,
                                           self, :stub, opts, &implementation)
      stubs.unshift stub
      stub
    end

build_expectation(error_generator, expectation_ordering) click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 142
    def build_expectation(error_generator, expectation_ordering)
      expected_from = IGNORED_BACKTRACE_LINE
      message_expectation_class.new(error_generator, expectation_ordering, expected_from, self)
    end

clear() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 119
    def clear
      expectations.clear
      stubs.clear
    end

configure_method() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 47
    def configure_method
      @original_visibility = [visibility, method_name]
      @method_stasher.stash unless @method_is_proxied
      define_proxy_method
    end

define_proxy_method() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 54
    def define_proxy_method
      return if @method_is_proxied

      save_original_method!
      definition_target.class_exec(self, method_name, visibility) do |method_double, method_name, visibility|
        define_method(method_name) do |*args, &block|
          method_double.proxy_method_invoked(self, *args, &block)
        end
        __send__(visibility, method_name)
      end

      @method_is_proxied = true
    end

definition_target() click to toggle source

    # File lib/rspec/mocks/method_double.rb, line 222
    def definition_target
      @definition_target ||= usable_rspec_prepended_module || object_singleton_class
    end

message_expectation_class() click to toggle source

The type of message expectation to create has been extracted to its own method so that subclasses can override it.

@private

    # File lib/rspec/mocks/method_double.rb, line 128
    def message_expectation_class
      MessageExpectation
    end

new_rspec_prepended_module() click to toggle source

    # File lib/rspec/mocks/method_double.rb, line 242
    def new_rspec_prepended_module
      RSpecPrependedModule.new.tap do |mod|
        object_singleton_class.__send__ :prepend, mod
      end
    end

object_singleton_class() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 42
    def object_singleton_class
      class << @object; self; end
    end

original_method() click to toggle source

    # File lib/rspec/mocks/method_double.rb, line 21
    def original_method
      # If original method is not present, uses the `method_missing`
      # handler of the object. This accounts for cases where the user has not
      # correctly defined `respond_to?`, and also 1.8 which does not provide
      # method handles for missing methods even if `respond_to?` is correct.
      @original_method ||=
        @method_stasher.original_method ||
        @proxy.original_method_handle_for(method_name) ||
        Proc.new do |*args, &block|
          @object.__send__(:method_missing, @method_name, *args, &block)
        end
    end

Also aliased as: save_original_method!
proxy_method_invoked(_obj, *args, &block) click to toggle source

The implementation of the proxied method. Subclasses may override this method to perform additional operations.

@private

    # File lib/rspec/mocks/method_double.rb, line 72
    def proxy_method_invoked(_obj, *args, &block)
      @proxy.message_received method_name, *args, &block
    end

raise_method_not_stubbed_error() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 200
    def raise_method_not_stubbed_error
      raise MockExpectationError, "The method `#{method_name}` was not stubbed or was already unstubbed"
    end

remove_stub() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 189
    def remove_stub
      raise_method_not_stubbed_error if stubs.empty?
      remove_stub_if_present
    end

remove_stub_if_present() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 195
    def remove_stub_if_present
      expectations.empty? ? reset : stubs.clear
    end

reset() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 113
    def reset
      restore_original_method
      clear
    end

restore_original_method() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 77
    def restore_original_method
      return show_frozen_warning if object_singleton_class.frozen?
      return unless @method_is_proxied

      remove_method_from_definition_target
      @method_stasher.restore if @method_stasher.method_is_stashed?
      restore_original_visibility

      @method_is_proxied = false
    end

restore_original_visibility() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 100
    def restore_original_visibility
      return unless @original_visibility &&
        MethodReference.method_defined_at_any_visibility?(object_singleton_class, @method_name)

      object_singleton_class.__send__(*@original_visibility)
    end

save_original_method!() click to toggle source
Alias for: original_method
setup_simple_method_double(method_name, response, collection, error_generator=nil, backtrace_line=nil) click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 174
    def setup_simple_method_double(method_name, response, collection, error_generator=nil, backtrace_line=nil)
      define_proxy_method

      me = SimpleMessageExpectation.new(method_name, response, error_generator, backtrace_line)
      collection.unshift me
      me
    end

show_frozen_warning() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 89
    def show_frozen_warning
      RSpec.warn_with(
        "WARNING: rspec-mocks was unable to restore the original `#{@method_name}` "            "method on #{@object.inspect} because it has been frozen.  If you reuse this "            "object, `#{@method_name}` will continue to respond with its stub implementation.",
        :call_site                      => nil,
        :use_spec_location_as_call_site => true
      )
    end

usable_rspec_prepended_module() click to toggle source

    # File lib/rspec/mocks/method_double.rb, line 226
    def usable_rspec_prepended_module
      @proxy.prepended_modules_of_singleton_class.each do |mod|
        # If we have one of our modules prepended before one of the user's
        # modules that defines the method, use that, since our module's
        # definition will take precedence.
        return mod if RSpecPrependedModule === mod

        # If we hit a user module with the method defined first,
        # we must create a new prepend module, even if one exists later,
        # because ours will only take precedence if it comes first.
        return new_rspec_prepended_module if mod.method_defined?(method_name)
      end

      nil
    end

verify() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 108
    def verify
      expectations.each { |e| e.verify_messages_received }
    end

visibility() click to toggle source

@private

    # File lib/rspec/mocks/method_double.rb, line 37
    def visibility
      @proxy.visibility_for(@method_name)
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.