# Class: Mocha::Configuration

Inherits:
  Object
  - Object
  - Mocha::Configuration
  show all

Defined in:
  lib/mocha/configuration.rb

## Overview

This class provides a number of ways to configure the library.

Typically the configuration is set globally in a `test_helper.rb` or `spec_helper.rb` file.

Examples:

Setting multiple configuration options

    Mocha.configure do |c|
      c.stubbing_method_unnecessarily = :prevent
      c.stubbing_method_on_non_mock_object = :warn
      c.stubbing_method_on_nil = :allow
    end

## Class Method Summary collapse

- .allow(action) { ... } ⇒ Object deprecated Deprecated.

  If a block is supplied, call Configuration.override with a `Hash` containing an entry with the `action` as the key and `:allow` as the value. If no block is supplied, call the appropriate `action` writer method with `value` set to `:allow` via configure. The writer method will be the one of the following corresponding to the `action`:

  - #stubbing_method_unnecessarily=

  - #stubbing_method_on_non_mock_object=

  - #stubbing_non_existent_method=

  - #stubbing_non_public_method=

  - #stubbing_method_on_nil=

- .override(temporary_options) { ... } ⇒ Object

  Temporarily modify Configuration options.

- .prevent(action) { ... } ⇒ Object deprecated Deprecated.

  If a block is supplied, call Configuration.override with a `Hash` containing an entry with the `action` as the key and `:prevent` as the value. If no block is supplied, call the appropriate `action` writer method with `value` set to `:prevent` via configure. The writer method will be the one of the following corresponding to the `action`:

  - #stubbing_method_unnecessarily=

  - #stubbing_method_on_non_mock_object=

  - #stubbing_non_existent_method=

  - #stubbing_non_public_method=

  - #stubbing_method_on_nil=

- .warn_when(action) { ... } ⇒ Object deprecated Deprecated.

  If a block is supplied, call Configuration.override with a `Hash` containing an entry with the `action` as the key and `:warn` as the value. If no block is supplied, call the appropriate `action` writer method with `value` set to `:warn` via configure. The writer method will be the one of the following corresponding to the `action`:

  - #stubbing_method_unnecessarily=

  - #stubbing_method_on_non_mock_object=

  - #stubbing_non_existent_method=

  - #stubbing_non_public_method=

  - #stubbing_method_on_nil=

## Instance Method Summary collapse

- #display_matching_invocations_on_failure=(value) ⇒ Object

  Display matching invocations alongside expectations on Mocha-related test failure.

- #reinstate_undocumented_behaviour_from_v1_9=(value) ⇒ Object deprecated Deprecated.

  Fix deprecation warnings caused by reliance on v1.9 behaviour and remove calls to this method.

- #stubbing_method_on_nil=(value) ⇒ Object

  Configure whether stubbing methods on the `nil` object is allowed.

- #stubbing_method_on_non_mock_object=(value) ⇒ Object

  Configure whether stubbing methods on non-mock objects is allowed.

- #stubbing_method_unnecessarily=(value) ⇒ Object

  Configure whether stubbing methods unnecessarily is allowed.

- #stubbing_non_existent_method=(value) ⇒ Object

  Configure whether stubbing of non-existent methods is allowed.

- #stubbing_non_public_method=(value) ⇒ Object

  Configure whether stubbing of non-public methods is allowed.

## Class Method Details

### .allow(action) { ... } ⇒ `Object`

Deprecated.

If a block is supplied, call override with a `Hash` containing an entry with the `action` as the key and `:allow` as the value. If no block is supplied, call the appropriate `action` writer method with `value` set to `:allow` via Mocha.configure. The writer method will be the one of the following corresponding to the `action`:

- #stubbing_method_unnecessarily=

- #stubbing_method_on_non_mock_object=

- #stubbing_non_existent_method=

- #stubbing_non_public_method=

- #stubbing_method_on_nil=

Allow the specified `action`.

Parameters:

- action (`Symbol`) —

  one of `:stubbing_method_unnecessarily`, `:stubbing_method_on_non_mock_object`, `:stubbing_non_existent_method`, `:stubbing_non_public_method`, `:stubbing_method_on_nil`.

Yields:

- optional block during which the configuration change will be changed before being returned to its original value at the end of the block.

    328
    329
    330
    331
    332
    333
    334
    335

    # File 'lib/mocha/configuration.rb', line 328

    def allow(action, &block)
      if block_given?
        Deprecation.warning("Use Mocha::Configuration.override(#{action}: :allow) with the same block")
      else
        Deprecation.warning("Use Mocha.configure { |c| c.#{action} = :allow }")
      end
      change_config action, :allow, &block
    end

### .override(temporary_options) { ... } ⇒ `Object`

Temporarily modify Mocha::Configuration options.

The supplied `temporary_options` will override the current configuration for the duration of the supplied block. The configuration will be returned to its original state when the block returns.

Examples:

Temporarily allow stubbing of `nil`

    Mocha::Configuration.override(stubbing_method_on_nil: :allow) do
      nil.stubs(:foo)
    end

Parameters:

- temporary_options (`Hash`) —

  the configuration options to apply for the duration of the block.

Yields:

- block during which the configuration change will be in force.

    407
    408
    409
    410
    411
    412
    413

    # File 'lib/mocha/configuration.rb', line 407

    def override(temporary_options)
      original_configuration = configuration
      @configuration = configuration.merge(new(temporary_options))
      yield
    ensure
      @configuration = original_configuration
    end

### .prevent(action) { ... } ⇒ `Object`

Deprecated.

If a block is supplied, call override with a `Hash` containing an entry with the `action` as the key and `:prevent` as the value. If no block is supplied, call the appropriate `action` writer method with `value` set to `:prevent` via Mocha.configure. The writer method will be the one of the following corresponding to the `action`:

- #stubbing_method_unnecessarily=

- #stubbing_method_on_non_mock_object=

- #stubbing_non_existent_method=

- #stubbing_non_public_method=

- #stubbing_method_on_nil=

Raise a StubbingError if the specified `action` is attempted.

Parameters:

- action (`Symbol`) —

  one of `:stubbing_method_unnecessarily`, `:stubbing_method_on_non_mock_object`, `:stubbing_non_existent_method`, `:stubbing_non_public_method`, `:stubbing_method_on_nil`.

Yields:

- optional block during which the configuration change will be changed before being returned to its original value at the end of the block.

    376
    377
    378
    379
    380
    381
    382
    383

    # File 'lib/mocha/configuration.rb', line 376

    def prevent(action, &block)
      if block_given?
        Deprecation.warning("Use Mocha::Configuration.override(#{action}: :prevent) with the same block")
      else
        Deprecation.warning("Use Mocha.configure { |c| c.#{action} = :prevent }")
      end
      change_config action, :prevent, &block
    end

### .warn_when(action) { ... } ⇒ `Object`

Deprecated.

If a block is supplied, call override with a `Hash` containing an entry with the `action` as the key and `:warn` as the value. If no block is supplied, call the appropriate `action` writer method with `value` set to `:warn` via Mocha.configure. The writer method will be the one of the following corresponding to the `action`:

- #stubbing_method_unnecessarily=

- #stubbing_method_on_non_mock_object=

- #stubbing_non_existent_method=

- #stubbing_non_public_method=

- #stubbing_method_on_nil=

Warn if the specified `action` is attempted.

Parameters:

- action (`Symbol`) —

  one of `:stubbing_method_unnecessarily`, `:stubbing_method_on_non_mock_object`, `:stubbing_non_existent_method`, `:stubbing_non_public_method`, `:stubbing_method_on_nil`.

Yields:

- optional block during which the configuration change will be changed before being returned to its original value at the end of the block.

    352
    353
    354
    355
    356
    357
    358
    359

    # File 'lib/mocha/configuration.rb', line 352

    def warn_when(action, &block)
      if block_given?
        Deprecation.warning("Use Mocha::Configuration.override(#{action}: :warn) with the same block")
      else
        Deprecation.warning("Use Mocha.configure { |c| c.#{action} = :warn }")
      end
      change_config action, :warn, &block
    end

## Instance Method Details

### #display_matching_invocations_on_failure=(value) ⇒ `Object`

Display matching invocations alongside expectations on Mocha-related test failure.

Examples:

Enable display of matching invocations

    Mocha.configure do |c|
      c.display_matching_invocations_on_failure = true
    end

    foo = mock('foo')
    foo.expects(:bar)
    foo.stubs(:baz).returns('baz').raises(RuntimeError).throws(:tag, 'value')

    foo.baz(1, 2)
    assert_raises(RuntimeError) { foo.baz(3, 4) }
    assert_throws(:tag) { foo.baz(5, 6) }

    not all expectations were satisfied
    unsatisfied expectations:
    - expected exactly once, invoked never: #<Mock:foo>.bar
    satisfied expectations:
    - allowed any number of times, invoked 3 times: #<Mock:foo>.baz(any_parameters)
      - #<Mock:foo>.baz(1, 2) # => "baz"
      - #<Mock:foo>.baz(3, 4) # => raised RuntimeError
      - #<Mock:foo>.baz(5, 6) # => threw (:tag, "value")

Parameters:

- value (`Boolean`) —

  `true` to enable display of matching invocations; disabled by default.

    242
    243
    244

    # File 'lib/mocha/configuration.rb', line 242

    def display_matching_invocations_on_failure=(value)
      @options[:display_matching_invocations_on_failure] = value
    end

### #reinstate_undocumented_behaviour_from_v1_9=(value) ⇒ `Object`

Deprecated.

Fix deprecation warnings caused by reliance on v1.9 behaviour and remove calls to this method.

Reinstate undocumented behaviour from v1.9

Previously when API#mock, API#stub, or API#stub_everything were called with the first argument being a symbol, they built an unnamed mock object and expected or stubbed the method identified by the symbol argument; subsequent arguments were ignored. Now these methods build a named mock with the name specified by the symbol argument; no methods are expected or stubbed and subsequent arguments are taken into account.

Previously if Expectation#yields or Expectation#multiple_yields was called on an expectation, but no block was given when the method was invoked, the instruction to yield was ignored. Now a `LocalJumpError` is raised.

Enabling this configuration option reinstates the previous behaviour, but displays a deprecation warning.

Examples:

Reinstate undocumented behaviour for API#mock

    Mocha.configure do |c|
      c.reinstate_undocumented_behaviour_from_v1_9 = true
    end

    foo = mock(:bar)
    foo.inspect # => #<Mock>

    not all expectations were satisfied
    unsatisfied expectations:
    - expected exactly once, invoked never: #<Mock>.foo

Reinstate undocumented behaviour for API#stub

    Mocha.configure do |c|
      c.reinstate_undocumented_behaviour_from_v1_9 = true
    end

    foo = stub(:bar)
    foo.inspect # => #<Mock>
    foo.bar # => nil

Reinstate undocumented behaviour for Expectation#yields

    foo = mock('foo')
    foo.stubs(:my_method).yields(1, 2)
    foo.my_method # => raises LocalJumpError when no block is supplied

    Mocha.configure do |c|
      c.reinstate_undocumented_behaviour_from_v1_9 = true
    end

    foo = mock('foo')
    foo.stubs(:my_method).yields(1, 2)
    foo.my_method # => does *not* raise LocalJumpError when no block is supplied

Parameters:

- value (`Boolean`) —

  `true` to reinstate undocumented behaviour; disabled by default.

    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310

    # File 'lib/mocha/configuration.rb', line 298

    def reinstate_undocumented_behaviour_from_v1_9=(value)
      if value
        sentence1 = 'Configuration#reinstate_undocumented_behaviour_from_v1_9= will be removed in the future.'
        sentence2 = 'Fix deprecation warnings caused by reliance on v1.9 behaviour.'
        sentence3 = 'See docs for API#mock, API#stub, API#stub_everything, Expectation#yields and Expectation#multiple_yields.'
        Deprecation.warning([sentence1, sentence2, sentence3].join(' '))
      else
        sentence1 = 'Configuration#reinstate_undocumented_behaviour_from_v1_9= is unnecessarily being set to false, because this is now the default value.'
        sentence2 = 'Configuration#reinstate_undocumented_behaviour_from_v1_9= will be removed in the future, so you should avoid calling it.'
        Deprecation.warning([sentence1, sentence2].join(' '))
      end
      @options[:reinstate_undocumented_behaviour_from_v1_9] = value
    end

### #stubbing_method_on_nil=(value) ⇒ `Object`

Configure whether stubbing methods on the `nil` object is allowed.

This is usually done accidentally, but there might be rare cases where it is intended.

This option only works for Ruby < v2.2.0. In later versions of Ruby `nil` is frozen and so a StubbingError will be raised if you attempt to stub a method on `nil`.

When `value` is `:allow`, do nothing. When `value` is `:warn`, display a warning. When `value` is `:prevent`, raise a StubbingError. This is the default.

Parameters:

- value (`Symbol`) —

  one of `:allow`, `:warn`, `:prevent`.

    208
    209
    210

    # File 'lib/mocha/configuration.rb', line 208

    def stubbing_method_on_nil=(value)
      @options[:stubbing_method_on_nil] = value
    end

### #stubbing_method_on_non_mock_object=(value) ⇒ `Object`

Configure whether stubbing methods on non-mock objects is allowed.

If you like the idea of mocking roles not objects and you don’t like stubbing concrete classes, this is the setting for you. However, while this restriction makes a lot of sense in Java with its explicit interfaces, it may be moot in Ruby where roles are probably best represented as Modules.

When `value` is `:allow`, do nothing. This is the default. When `value` is `:warn`, display a warning. When `value` is `:prevent`, raise a StubbingError.

Examples:

Preventing stubbing of a method on a non-mock object

    Mocha.configure do |c|
      c.stubbing_method_on_non_mock_object = :prevent
    end

    class Example
      def example_method; end
    end

    example = Example.new
    example.stubs(:example_method)
    # => Mocha::StubbingError: stubbing method on non-mock object:
    # =>   #<Example:0x593620>.example_method

Parameters:

- value (`Symbol`) —

  one of `:allow`, `:warn`, `:prevent`.

    120
    121
    122

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

    def stubbing_method_on_non_mock_object=(value)
      @options[:stubbing_method_on_non_mock_object] = value
    end

### #stubbing_method_unnecessarily=(value) ⇒ `Object`

Configure whether stubbing methods unnecessarily is allowed.

This is useful for identifying unused stubs. Unused stubs are often accidentally introduced when code is refactored.

When `value` is `:allow`, do nothing. This is the default. When `value` is `:warn`, display a warning. When `value` is `:prevent`, raise a StubbingError.

Examples:

Preventing unnecessary stubbing of a method

    Mocha.configure do |c|
      c.stubbing_method_unnecessarily = :prevent
    end

    example = mock('example')
    example.stubs(:unused_stub)
    # => Mocha::StubbingError: stubbing method unnecessarily:
    # =>   #<Mock:example>.unused_stub(any_parameters)

Parameters:

- value (`Symbol`) —

  one of `:allow`, `:warn`, `:prevent`.

    87
    88
    89

    # File 'lib/mocha/configuration.rb', line 87

    def stubbing_method_unnecessarily=(value)
      @options[:stubbing_method_unnecessarily] = value
    end

### #stubbing_non_existent_method=(value) ⇒ `Object`

Configure whether stubbing of non-existent methods is allowed.

This is useful if you want to ensure that methods you’re mocking really exist. A common criticism of unit tests with mock objects is that such a test may (incorrectly) pass when an equivalent non-mocking test would (correctly) fail. While you should always have some integration tests, particularly for critical business functionality, this Mocha configuration setting should catch scenarios when mocked methods and real methods have become misaligned.

When `value` is `:allow`, do nothing. This is the default. When `value` is `:warn`, display a warning. When `value` is `:prevent`, raise a StubbingError.

Examples:

Preventing stubbing of a non-existent method

    Mocha.configure do |c|
      c.stubbing_non_existent_method = :prevent
    end

    class Example
    end

    example = Example.new
    example.stubs(:method_that_doesnt_exist)
    # => Mocha::StubbingError: stubbing non-existent method:
    # =>   #<Example:0x593760>.method_that_doesnt_exist

Parameters:

- value (`Symbol`) —

  one of `:allow`, `:warn`, `:prevent`.

    153
    154
    155

    # File 'lib/mocha/configuration.rb', line 153

    def stubbing_non_existent_method=(value)
      @options[:stubbing_non_existent_method] = value
    end

### #stubbing_non_public_method=(value) ⇒ `Object`

Configure whether stubbing of non-public methods is allowed.

Many people think that it’s good practice only to mock public methods. This is one way to prevent your tests being too tightly coupled to the internal implementation of a class. Such tests tend to be very brittle and not much use when refactoring.

When `value` is `:allow`, do nothing. This is the default. When `value` is `:warn`, display a warning. When `value` is `:prevent`, raise a StubbingError.

Examples:

Preventing stubbing of a non-public method

    Mocha.configure do |c|
      c.stubbing_non_public_method = :prevent
    end

    class Example
      def internal_method; end
      private :internal_method
    end

    example = Example.new
    example.stubs(:internal_method)
    # => Mocha::StubbingError: stubbing non-public method:
    # =>   #<Example:0x593530>.internal_method

Parameters:

- value (`Symbol`) —

  one of `:allow`, `:warn`, `:prevent`.

    187
    188
    189

    # File 'lib/mocha/configuration.rb', line 187

    def stubbing_non_public_method=(value)
      @options[:stubbing_non_public_method] = value
    end