# Module: Mocha::ObjectMethods

Extended by:
  IgnoringWarning

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

    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104

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

    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 |method_name, *args|
        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

    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150

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

    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 |method_name, *args|
        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.

    175
    176
    177
    178
    179
    180
    181

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

    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