# Module: Mocha::ObjectMethods

Defined in:
  lib/mocha/object_methods.rb

## Overview

Methods added to all objects to allow mocking and stubbing on real (i.e. non-mock) objects.

Both #expects and #stubs return an Expectation which can be further modified by methods on Expectation.

## Instance Method Summary collapse

- #expects(expected_methods_vs_return_values) ⇒ Expectation

  Adds an expectation that the specified method must be called exactly once with any parameters.

- #stubs(stubbed_methods_vs_return_values) ⇒ Expectation

  Adds an expectation that the specified method may be called any number of times with any parameters.

- #unstub(*method_names) ⇒ Object

  Removes the specified stubbed methods (added by calls to #expects or #stubs) and all expectations associated with them.

## Instance Method Details

### #expects(method_name) ⇒ `Expectation` #expects(expected_methods_vs_return_values) ⇒ `Expectation`

Adds an expectation that the specified method must be called exactly once with any parameters.

The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.

Examples:

Setting up an expectation on a non-mock object.

    product = Product.new
    product.expects(:save).returns(true)
    assert_equal true, product.save

Setting up multiple expectations on a non-mock object.

    product = Product.new
    product.expects(:valid? => true, :save => true)

    # exactly equivalent to

    product = Product.new
    product.expects(:valid?).returns(true)
    product.expects(:save).returns(true)

Overloads:

- #expects(method_name) ⇒ `Expectation`

  Parameters:

  - method_name (`Symbol`, `String`) —

    name of expected method

- #expects(expected_methods_vs_return_values) ⇒ `Expectation`

  Parameters:

  - expected_methods_vs_return_values (`Hash`) —

    expected method name symbols as keys and corresponding return values as values - these expectations are setup as if #expects were called multiple times.

Returns:

- (`Expectation`) —

  last-built expectation which can be further modified by methods on Expectation.

Raises:

- (`StubbingError`) —

  if attempting to stub method which is not allowed.

See Also:

- Mock#expects

    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90

    # File 'lib/mocha/object_methods.rb', line 71

    def expects(expected_methods_vs_return_values)
      if expected_methods_vs_return_values.to_s =~ /the[^a-z]*spanish[^a-z]*inquisition/i
        raise ExpectationErrorFactory.build('NOBODY EXPECTS THE SPANISH INQUISITION!')
      end
      if frozen?
        raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
      end
      expectation = nil
      mockery = Mocha::Mockery.instance
      iterator = ArgumentIterator.new(expected_methods_vs_return_values)
      iterator.each do |*args|
        method_name = args.shift
        mockery.on_stubbing(self, method_name)
        method = stubba_method.new(stubba_object, method_name)
        mockery.stubba.stub(method)
        expectation = mocha.expects(method_name, caller)
        expectation.returns(args.shift) unless args.empty?
      end
      expectation
    end

### #stubs(method_name) ⇒ `Expectation` #stubs(stubbed_methods_vs_return_values) ⇒ `Expectation`

Adds an expectation that the specified method may be called any number of times with any parameters.

The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.

Examples:

Setting up a stubbed methods on a non-mock object.

    product = Product.new
    product.stubs(:save).returns(true)
    assert_equal true, product.save

Setting up multiple stubbed methods on a non-mock object.

    product = Product.new
    product.stubs(:valid? => true, :save => true)

    # exactly equivalent to

    product = Product.new
    product.stubs(:valid?).returns(true)
    product.stubs(:save).returns(true)

Overloads:

- #stubs(method_name) ⇒ `Expectation`

  Parameters:

  - method_name (`Symbol`, `String`) —

    name of stubbed method

- #stubs(stubbed_methods_vs_return_values) ⇒ `Expectation`

  Parameters:

  - stubbed_methods_vs_return_values (`Hash`) —

    stubbed method name symbols as keys and corresponding return values as values - these stubbed methods are setup as if #stubs were called multiple times.

Returns:

- (`Expectation`) —

  last-built expectation which can be further modified by methods on Expectation.

Raises:

- (`StubbingError`) —

  if attempting to stub method which is not allowed.

See Also:

- Mock#stubs

    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136

    # File 'lib/mocha/object_methods.rb', line 120

    def stubs(stubbed_methods_vs_return_values)
      if frozen?
        raise StubbingError.new("can't stub method on frozen object: #{mocha_inspect}", caller)
      end
      expectation = nil
      mockery = Mocha::Mockery.instance
      iterator = ArgumentIterator.new(stubbed_methods_vs_return_values)
      iterator.each do |*args|
        method_name = args.shift
        mockery.on_stubbing(self, method_name)
        method = stubba_method.new(stubba_object, method_name)
        mockery.stubba.stub(method)
        expectation = mocha.stubs(method_name, caller)
        expectation.returns(args.shift) unless args.empty?
      end
      expectation
    end

### #unstub(*method_names) ⇒ `Object`

Removes the specified stubbed methods (added by calls to #expects or #stubs) and all expectations associated with them.

Restores the original behaviour of the methods before they were stubbed. This is normally done automatically at the end of each test, but in some circumstances you may want to do it before the end of the test.

WARNING: If you #unstub a method which still has unsatisfied expectations, you may be removing the only way those expectations can be satisfied. Use #unstub with care.

Examples:

Stubbing and unstubbing a method on a real (non-mock) object.

    multiplier = Multiplier.new
    multiplier.double(2) # => 4
    multiplier.stubs(:double).raises # new behaviour defined
    multiplier.double(2) # => raises exception
    multiplier.unstub(:double) # original behaviour restored
    multiplier.double(2) # => 4

Unstubbing multiple methods on a real (non-mock) object.

    multiplier.unstub(:double, :triple)

    # exactly equivalent to

    multiplier.unstub(:double)
    multiplier.unstub(:triple)

Parameters:

- method_names (`Array<Symbol>`) —

  names of methods to unstub.

    161
    162
    163
    164
    165
    166
    167

    # File 'lib/mocha/object_methods.rb', line 161

    def unstub(*method_names)
      mockery = Mocha::Mockery.instance
      method_names.each do |method_name|
        method = stubba_method.new(stubba_object, method_name)
        mockery.stubba.unstub(method)
      end
    end