# Class: Mocha::Expectation

Inherits:
  Object
  - Object
  - Mocha::Expectation
  show all

Defined in:
  lib/mocha/expectation.rb

## Overview

Methods on expectations returned from Mock#expects, Mock#stubs, ObjectMethods#expects and ObjectMethods#stubs.

## Instance Method Summary collapse

- #at_least(minimum_number_of_times) ⇒ Expectation

  Modifies expectation so that the expected method must be called at least a `minimum_number_of_times`.

- #at_least_once ⇒ Expectation

  Modifies expectation so that the expected method must be called at least once.

- #at_most(maximum_number_of_times) ⇒ Expectation

  Modifies expectation so that the expected method must be called at most a `maximum_number_of_times`.

- #at_most_once ⇒ Expectation

  Modifies expectation so that the expected method must be called at most once.

- #in_sequence(sequence, *sequences) ⇒ Expectation

  Constrains the expectation so that it must be invoked at the current point in the `sequence`.

- #multiple_yields(*parameter_groups) ⇒ Expectation

  Modifies expectation so that when the expected method is called, it yields multiple times per invocation with the specified `parameter_groups`.

- #never ⇒ Expectation

  Modifies expectation so that the expected method must never be called.

- #once ⇒ Expectation

  Modifies expectation so that the expected method must be called exactly once.

- #raises(exception = RuntimeError, message = nil) ⇒ Expectation

  Modifies expectation so that when the expected method is called, it raises the specified `exception` with the specified `message` i.e.

- #returns(*values) ⇒ Expectation

  Modifies expectation so that when the expected method is called, it returns the specified `value`.

- #then(state = nil) ⇒ Expectation

  The same expectation, thereby allowing invocations of other Expectation methods to be chained.

- #thrice ⇒ Expectation

  Modifies expectation so that the expected method must be called exactly three times.

- #throws(tag, object = nil) ⇒ Expectation

  Modifies expectation so that when the expected method is called, it throws the specified `tag` with the specific return value `object` i.e.

- #times(range_or_number) ⇒ Expectation

  Modifies expectation so that the number of invocations of the expected method must be within a specified range or exactly equal to a specified number.

- #twice ⇒ Expectation

  Modifies expectation so that the expected method must be called exactly twice.

- #when(state_predicate) ⇒ Expectation

  Constrains the expectation to occur only when the `state_machine` is in the state specified by `state_predicate`.

- #with(*expected_parameters_or_matchers) {|actual_parameters| ... } ⇒ Expectation

  Modifies expectation so that the expected method must be called with `expected_parameters_or_matchers`.

- #with_block_given ⇒ Expectation

  Modifies expectation so that the expected method must be called with a block.

- #with_no_block_given ⇒ Expectation

  Modifies expectation so that the expected method must be called without a block.

- #yields(*parameters) ⇒ Expectation

  Modifies expectation so that when the expected method is called, it yields to the block with the specified `parameters`.

## Instance Method Details

### #at_least(minimum_number_of_times) ⇒ `Expectation`

Modifies expectation so that the expected method must be called at least a `minimum_number_of_times`.

#### Examples:

#####

Expected method must be called at least twice.

    object = mock()
    object.expects(:expected_method).at_least(2)
    3.times { object.expected_method }
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).at_least(2)
    object.expected_method
    # => verify fails

Parameters:

- minimum_number_of_times (`Integer`) —

  minimum number of expected invocations.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    164
    165
    166
    167

    # File 'lib/mocha/expectation.rb', line 164

    def at_least(minimum_number_of_times)
      @cardinality.at_least(minimum_number_of_times)
      self
    end

### #at_least_once ⇒ `Expectation`

Modifies expectation so that the expected method must be called at least once. This is equivalent to calling #at_least with an argument of `1`.

#### Examples:

#####

Expected method must be called at least once.

    object = mock()
    object.expects(:expected_method).at_least_once
    object.expected_method
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).at_least_once
    # => verify fails

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    182
    183
    184

    # File 'lib/mocha/expectation.rb', line 182

    def at_least_once
      at_least(1)
    end

### #at_most(maximum_number_of_times) ⇒ `Expectation`

Modifies expectation so that the expected method must be called at most a `maximum_number_of_times`.

#### Examples:

#####

Expected method must be called at most twice.

    object = mock()
    object.expects(:expected_method).at_most(2)
    2.times { object.expected_method }
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).at_most(2)
    3.times { object.expected_method } # => unexpected invocation

Parameters:

- maximum_number_of_times (`Integer`) —

  maximum number of expected invocations.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    200
    201
    202
    203

    # File 'lib/mocha/expectation.rb', line 200

    def at_most(maximum_number_of_times)
      @cardinality.at_most(maximum_number_of_times)
      self
    end

### #at_most_once ⇒ `Expectation`

Modifies expectation so that the expected method must be called at most once. This is equivalent to calling #at_most with an argument of `1`.

#### Examples:

#####

Expected method must be called at most once.

    object = mock()
    object.expects(:expected_method).at_most_once
    object.expected_method
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).at_most_once
    2.times { object.expected_method } # => unexpected invocation

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    218
    219
    220

    # File 'lib/mocha/expectation.rb', line 218

    def at_most_once
      at_most(1)
    end

### #in_sequence(sequence, *sequences) ⇒ `Expectation`

Constrains the expectation so that it must be invoked at the current point in the `sequence`.

To expect a sequence of invocations, write the expectations in order and add the `in_sequence(sequence)` clause to each one.

Expectations in a `sequence` can have any invocation count.

If an expectation in a sequence is stubbed, rather than expected, it can be skipped in the `sequence`.

An expected method can appear in multiple sequences.

#### Examples:

#####

Ensure methods are invoked in a specified order.

    breakfast = sequence('breakfast')

    egg = mock('egg')
    egg.expects(:crack).in_sequence(breakfast)
    egg.expects(:fry).in_sequence(breakfast)
    egg.expects(:eat).in_sequence(breakfast)

Parameters:

- sequence (`Sequence`) —

  sequence in which expected method should appear.

- sequences (`*Array<Sequence>`) —

  more sequences in which expected method should appear.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- API#sequence

    643
    644
    645
    646

    # File 'lib/mocha/expectation.rb', line 643

    def in_sequence(sequence, *sequences)
      sequences.unshift(sequence).each { |seq| add_in_sequence_ordering_constraint(seq) }
      self
    end

### #multiple_yields(*parameter_groups) ⇒ `Expectation`

Modifies expectation so that when the expected method is called, it yields multiple times per invocation with the specified `parameter_groups`.

If no block is provided, the method will still attempt to yield resulting in a `LocalJumpError`. Note that this is what would happen if a “real” (non-mock) method implementation tried to yield to a non-existent block.

#### Examples:

#####

When `foreach` is called, the stub will invoke the block twice, the first time it passes [‘row1_col1’, ‘row1_col2’] as the parameters, and the second time it passes [‘row2_col1’, ”] as the parameters.

    csv = mock()
    csv.expects(:foreach).with("path/to/file.csv").multiple_yields(['row1_col1', 'row1_col2'], ['row2_col1', ''])
    rows = []
    csv.foreach { |row| rows << row }
    rows # => [['row1_col1', 'row1_col2'], ['row2_col1', '']]

#####

Yield different groups of parameters on different invocations of the expected method. Simulating a situation where the CSV file at ‘path/to/file.csv’ has been modified between the two calls to `foreach`.

    csv = mock()
    csv.stubs(:foreach).with("path/to/file.csv").multiple_yields(['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']).then.multiple_yields(['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2'])
    rows_from_first_invocation = []
    rows_from_second_invocation = []
    csv.foreach { |row| rows_from_first_invocation << row } # first invocation
    csv.foreach { |row| rows_from_second_invocation << row } # second invocation
    rows_from_first_invocation # => [['old_row1_col1', 'old_row1_col2'], ['old_row2_col1', '']]
    rows_from_second_invocation # => [['new_row1_col1', ''], ['new_row2_col1', 'new_row2_col2']]

Parameters:

- parameter_groups (`*Array<Array>`) —

  each element of `parameter_groups` should iself be an `Array` representing the parameters to be passed to the block for a single yield. Any element of `parameter_groups` that is not an `Array` is wrapped in an `Array`.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- #then

    430
    431
    432
    433

    # File 'lib/mocha/expectation.rb', line 430

    def multiple_yields(*parameter_groups)
      @yield_parameters.add(*parameter_groups)
      self
    end

### #never ⇒ `Expectation`

Modifies expectation so that the expected method must never be called.

#### Examples:

#####

Expected method must never be called.

    object = mock()
    object.expects(:expected_method).never
    object.expected_method # => unexpected invocation

    object = mock()
    object.expects(:expected_method).never
    # => verify succeeds

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    144
    145
    146
    147

    # File 'lib/mocha/expectation.rb', line 144

    def never
      @cardinality.exactly(0)
      self
    end

### #once ⇒ `Expectation`

Modifies expectation so that the expected method must be called exactly once. This is equivalent to calling #times with an argument of `1`.

Note that this is the default behaviour for an expectation, but you may wish to use it for clarity/emphasis.

#### Examples:

#####

Expected method must be invoked exactly once.

    object = mock()
    object.expects(:expected_method).once
    object.expected_method
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).once
    object.expected_method
    object.expected_method # => unexpected invocation

    object = mock()
    object.expects(:expected_method).once
    # => verify fails

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    127
    128
    129
    130

    # File 'lib/mocha/expectation.rb', line 127

    def once
      @cardinality.exactly(1)
      self
    end

### #raises ⇒ `Expectation` #raises(exception) ⇒ `Expectation` #raises(exception, message) ⇒ `Expectation`

Modifies expectation so that when the expected method is called, it raises the specified `exception` with the specified `message` i.e. calls `Kernel#raise(exception, message)`.

#### Examples:

#####

Raise specified exception if expected method is invoked.

    object = stub()
    object.stubs(:expected_method).raises(Exception, 'message')
    object.expected_method # => raises exception of class Exception and with message 'message'

#####

Raise custom exception with extra constructor parameters by passing in an instance of the exception.

    object = stub()
    object.stubs(:expected_method).raises(MyException.new('message', 1, 2, 3))
    object.expected_method # => raises the specified instance of MyException

#####

Raise different exceptions on consecutive invocations of the expected method.

    object = stub()
    object.stubs(:expected_method).raises(Exception1).then.raises(Exception2)
    object.expected_method # => raises exception of class Exception1
    object.expected_method # => raises exception of class Exception2

#####

Raise an exception on first invocation of expected method and then return values on subsequent invocations.

    object = stub()
    object.stubs(:expected_method).raises(Exception).then.returns(2, 3)
    object.expected_method # => raises exception of class Exception1
    object.expected_method # => 2
    object.expected_method # => 3

Parameters:

- exception (`Class`, `Exception`, `String`, `#exception`) (defaults to: `RuntimeError`) —

  exception to be raised or message to be passed to RuntimeError.

- message (`String`) (defaults to: `nil`) —

  exception message.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- Kernel#raise
- #then

    517
    518
    519
    520

    # File 'lib/mocha/expectation.rb', line 517

    def raises(exception = RuntimeError, message = nil)
      @return_values += ReturnValues.new(ExceptionRaiser.new(exception, message))
      self
    end

### #returns(value) ⇒ `Expectation` #returns(*values) ⇒ `Expectation`

Modifies expectation so that when the expected method is called, it returns the specified `value`.

#### Examples:

#####

Return the same value on every invocation.

    object = mock()
    object.stubs(:stubbed_method).returns('result')
    object.stubbed_method # => 'result'
    object.stubbed_method # => 'result'

#####

Return a different value on consecutive invocations.

    object = mock()
    object.stubs(:stubbed_method).returns(1, 2)
    object.stubbed_method # => 1
    object.stubbed_method # => 2

#####

Alternative way to return a different value on consecutive invocations.

    object = mock()
    object.stubs(:expected_method).returns(1, 2).then.returns(3)
    object.expected_method # => 1
    object.expected_method # => 2
    object.expected_method # => 3

#####

May be called in conjunction with #raises on the same expectation.

    object = mock()
    object.stubs(:expected_method).returns(1, 2).then.raises(Exception)
    object.expected_method # => 1
    object.expected_method # => 2
    object.expected_method # => raises exception of class Exception1

#####

Note that in Ruby a method returning multiple values is exactly equivalent to a method returning an `Array` of those values.

    object = mock()
    object.stubs(:expected_method).returns([1, 2])
    x, y = object.expected_method
    x # => 1
    y # => 2

Overloads:

- #returns(value) ⇒ `Expectation`

  Parameters:

  - value (`Object`) —

    value to return on invocation of expected method.

- #returns(*values) ⇒ `Expectation`

  Parameters:

  - values (`*Array`) —

    values to return on consecutive invocations of expected method.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- #then

    477
    478
    479
    480

    # File 'lib/mocha/expectation.rb', line 477

    def returns(*values)
      @return_values += ReturnValues.build(*values)
      self
    end

### #then ⇒ `Expectation` #then(state) ⇒ `Expectation`

Returns the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

#### Examples:

#####

Using #then as syntactic sugar when specifying values to be returned and exceptions to be raised on consecutive invocations of the expected method.

    object = mock()
    object.stubs(:expected_method).returns(1, 2).then.raises(Exception).then.returns(4)
    object.expected_method # => 1
    object.expected_method # => 2
    object.expected_method # => raises exception of class Exception
    object.expected_method # => 4

#####

Using #then to change the `state` of a `state_machine` on the invocation of an expected method.

    power = states('power').starts_as('off')

    radio = mock('radio')
    radio.expects(:switch_on).then(power.is('on'))
    radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
    radio.expects(:adjust_volume).with(+5).when(power.is('on'))
    radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
    radio.expects(:adjust_volume).with(-5).when(power.is('on'))
    radio.expects(:switch_off).then(power.is('off'))

Overloads:

- #then ⇒ `Expectation`

  Used as syntactic sugar to improve readability. It has no effect on state of the expectation.

- #then(state) ⇒ `Expectation`

  Used to change the `state_machine` to the specified state when the expected invocation occurs.

  Parameters:

  - state (`StateMachine::State`) —

    state_machine.is(state_name) provides a mechanism to change the `state_machine` into the state specified by `state_name` when the expected method is invoked.

  See Also:

  - API#states
  - StateMachine
  - #when

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    591
    592
    593
    594

    # File 'lib/mocha/expectation.rb', line 591

    def then(state = nil)
      add_side_effect(ChangeStateSideEffect.new(state)) if state
      self
    end

### #thrice ⇒ `Expectation`

Modifies expectation so that the expected method must be called exactly three times. This is equivalent to calling #times with an argument of `3`.

#### Examples:

#####

Expected method must be invoked exactly three times.

    object = mock()
    object.expects(:expected_method).thrice
    object.expected_method
    object.expected_method
    object.expected_method
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).thrice
    object.expected_method
    object.expected_method
    object.expected_method
    object.expected_method # => unexpected invocation

    object = mock()
    object.expects(:expected_method).thrice
    object.expected_method
    object.expected_method
    # => verify fails

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    76
    77
    78
    79

    # File 'lib/mocha/expectation.rb', line 76

    def thrice
      @cardinality.exactly(3)
      self
    end

### #throw(tag) ⇒ `Expectation` #throw(tag, object) ⇒ `Expectation`

Modifies expectation so that when the expected method is called, it throws the specified `tag` with the specific return value `object` i.e. calls `Kernel#throw(tag, object)`.

#### Examples:

#####

Throw tag when expected method is invoked.

    object = stub()
    object.stubs(:expected_method).throws(:done)
    object.expected_method # => throws tag :done

#####

Throw tag with return value `object` c.f. `Kernel#throw`.

    object = stub()
    object.stubs(:expected_method).throws(:done, 'result')
    object.expected_method # => throws tag :done and causes catch block to return 'result'

#####

Throw different tags on consecutive invocations of the expected method.

    object = stub()
    object.stubs(:expected_method).throws(:done).then.throws(:continue)
    object.expected_method # => throws :done
    object.expected_method # => throws :continue

#####

Throw tag on first invocation of expected method and then return values for subsequent invocations.

    object = stub()
    object.stubs(:expected_method).throws(:done).then.returns(2, 3)
    object.expected_method # => throws :done
    object.expected_method # => 2
    object.expected_method # => 3

Parameters:

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

  tag to throw to transfer control to the active catch block.

- object (`Object`) (defaults to: `nil`) —

  return value for the catch block.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- Kernel#throw
- #then

    556
    557
    558
    559

    # File 'lib/mocha/expectation.rb', line 556

    def throws(tag, object = nil)
      @return_values += ReturnValues.new(Thrower.new(tag, object))
      self
    end

### #times(range_or_number) ⇒ `Expectation`

Modifies expectation so that the number of invocations of the expected method must be within a specified range or exactly equal to a specified number.

#### Examples:

#####

Specifying an exact number of expected invocations.

    object = mock()
    object.expects(:expected_method).times(3)
    3.times { object.expected_method }
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).times(3)
    2.times { object.expected_method }
    # => verify fails

#####

Specifying a range for the number of expected invocations.

    object = mock()
    object.expects(:expected_method).times(2..4)
    3.times { object.expected_method }
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).times(2..4)
    object.expected_method
    # => verify fails

Parameters:

- range_or_number (`Range`, `Integer`) —

  specifies the allowable range for the number of expected invocations or the specified number of expected invocations.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    47
    48
    49
    50

    # File 'lib/mocha/expectation.rb', line 47

    def times(range_or_number)
      @cardinality.times(range_or_number)
      self
    end

### #twice ⇒ `Expectation`

Modifies expectation so that the expected method must be called exactly twice. This is equivalent to calling #times with an argument of `2`.

#### Examples:

#####

Expected method must be invoked exactly twice.

    object = mock()
    object.expects(:expected_method).twice
    object.expected_method
    object.expected_method
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).twice
    object.expected_method
    object.expected_method
    object.expected_method # => unexpected invocation

    object = mock()
    object.expects(:expected_method).twice
    object.expected_method
    # => verify fails

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    102
    103
    104
    105

    # File 'lib/mocha/expectation.rb', line 102

    def twice
      @cardinality.exactly(2)
      self
    end

### #when(state_predicate) ⇒ `Expectation`

Constrains the expectation to occur only when the `state_machine` is in the state specified by `state_predicate`.

#### Examples:

#####

Using #when to only allow invocation of methods when “power” state machine is in the “on” state.

    power = states('power').starts_as('off')

    radio = mock('radio')
    radio.expects(:switch_on).then(power.is('on'))
    radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on'))
    radio.expects(:adjust_volume).with(+5).when(power.is('on'))
    radio.expects(:select_channel).with('BBC World Service').when(power.is('on'))
    radio.expects(:adjust_volume).with(-5).when(power.is('on'))
    radio.expects(:switch_off).then(power.is('off'))

Parameters:

- state_predicate (`StateMachine::StatePredicate`) —

  `state_machine.is(state_name)` provides a mechanism to determine whether the `state_machine` is in the state specified by `state_predicate` when the expected method is invoked.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- API#states
- StateMachine
- #then

    615
    616
    617
    618

    # File 'lib/mocha/expectation.rb', line 615

    def when(state_predicate)
      add_ordering_constraint(InStateOrderingConstraint.new(state_predicate))
      self
    end

### #with(*expected_parameters_or_matchers) {|actual_parameters| ... } ⇒ `Expectation`

Modifies expectation so that the expected method must be called with `expected_parameters_or_matchers`.

May be used with Ruby literals or variables for exact matching or with parameter matchers for less-specific matching, e.g. ParameterMatchers::Methods#includes, ParameterMatchers::Methods#has_key, etc. See ParameterMatchers for a list of all available parameter matchers.

Alternatively a block argument can be passed to #with to implement custom parameter matching. The block receives the `*actual_parameters` as its arguments and should return `true` if they are acceptable or `false` otherwise. See the example below where a method is expected to be called with a value divisible by 4. The block argument takes precedence over `expected_parameters_or_matchers`. The block may be called multiple times per invocation of the expected method and so it should be idempotent.

Note that if #with is called multiple times on the same expectation, the last call takes precedence; other calls are ignored.

Positional arguments were separated from keyword arguments in Ruby v3 (see this article). In relation to this a new configuration option (Configuration#strict_keyword_argument_matching=) is available in Ruby >= 2.7.

When Configuration#strict_keyword_argument_matching= is set to `false` (which is the default in Ruby v2.7), a positional `Hash` and a set of keyword arguments passed to #with are treated the same for the purposes of parameter matching. However, a deprecation warning will be displayed if a positional `Hash` matches a set of keyword arguments or vice versa.

When Configuration#strict_keyword_argument_matching= is set to `true` (which is the default in Ruby >= v3.0), an actual positional `Hash` will not match an expected set of keyword arguments; and vice versa, an actual set of keyword arguments will not match an expected positional `Hash`, i.e. the parameter matching is stricter.

#### Examples:

#####

Expected method must be called with exact parameter values.

    object = mock()
    object.expects(:expected_method).with(:param1, :param2)
    object.expected_method(:param1, :param2)
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).with(:param1, :param2)
    object.expected_method(:param3)
    # => verify fails

#####

Expected method must be called with parameters matching parameter matchers.

    object = mock()
    object.expects(:expected_method).with(includes('string2'), anything)
    object.expected_method(['string1', 'string2'], 'any-old-value')
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).with(includes('string2'), anything)
    object.expected_method(['string1'], 'any-old-value')
    # => verify fails

#####

Loose keyword argument matching (default in Ruby v2.7).

    Mocha.configure do |c|
      c.strict_keyword_argument_matching = false
    end

    class Example
      def foo(a, bar:); end
    end

    example = Example.new
    example.expects(:foo).with('a', bar: 'b')
    example.foo('a', { bar: 'b' })
    # This passes the test, but would result in an ArgumentError in practice

#####

Strict keyword argument matching (default in Ruby >= 3.0).

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

    class Example
      def foo(a, bar:); end
    end

    example = Example.new
    example.expects(:foo).with('a', bar: 'b')
    example.foo('a', { bar: 'b' })
    # This now fails as expected

#####

Using a block argument to expect the method to be called with a value divisible by 4.

    object = mock()
    object.expects(:expected_method).with() { |value| value % 4 == 0 }
    object.expected_method(16)
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).with() { |value| value % 4 == 0 }
    object.expected_method(17)
    # => verify fails

#####

Extracting a custom matcher into an instance method on the test class.

    class MyTest < Minitest::Test
      def test_expected_method_is_called_with_a_value_divisible_by_4
        object = mock()
        object.expects(:expected_method).with(&method(:divisible_by_4))
        object.expected_method(16)
        # => verify succeeds
      end

      private

      def divisible_by_4(value)
        value % 4 == 0
      end
    end

Parameters:

- expected_parameters_or_matchers (`Array<Object,ParameterMatchers::BaseMethods>`) —

  expected parameter values or parameter matchers.

Yields:

- optional block specifying custom matching.

Yield Parameters:

- actual_parameters (`Array<Object>`) —

  parameters with which expected method was invoked.

Yield Returns:

- (`Boolean`) —

  `true` if `actual_parameters` are acceptable; `false` otherwise.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- ParameterMatchers
- Configuration#strict_keyword_argument_matching=

    324
    325
    326
    327

    # File 'lib/mocha/expectation.rb', line 324

    def with(*expected_parameters_or_matchers, &matching_block)
      @parameters_matcher = ParametersMatcher.new(expected_parameters_or_matchers, self, &matching_block)
      self
    end

### #with_block_given ⇒ `Expectation`

Modifies expectation so that the expected method must be called with a block.

#### Examples:

#####

Expected method must be called with a block.

    object = mock()
    object.expects(:expected_method).with_block_given
    object.expected_method { 1 + 1 }
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).with_block_given
    object.expected_method
    # => verify fails

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    344
    345
    346
    347

    # File 'lib/mocha/expectation.rb', line 344

    def with_block_given
      @block_matcher = BlockMatchers::BlockGiven.new
      self
    end

### #with_no_block_given ⇒ `Expectation`

Modifies expectation so that the expected method must be called without a block.

#### Examples:

#####

Expected method must be called without a block.

    object = mock()
    object.expects(:expected_method).with_no_block_given
    object.expected_method
    # => verify succeeds

    object = mock()
    object.expects(:expected_method).with_block_given
    object.expected_method { 1 + 1 }
    # => verify fails

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

    363
    364
    365
    366

    # File 'lib/mocha/expectation.rb', line 363

    def with_no_block_given
      @block_matcher = BlockMatchers::NoBlockGiven.new
      self
    end

### #yields(*parameters) ⇒ `Expectation`

Modifies expectation so that when the expected method is called, it yields to the block with the specified `parameters`.

If no `parameters` are specified, it yields to the block without any parameters.

If no block is provided, the method will still attempt to yield resulting in a `LocalJumpError`. Note that this is what would happen if a “real” (non-mock) method implementation tried to yield to a non-existent block.

May be called multiple times on the same expectation for consecutive invocations.

#### Examples:

#####

Yield when expected method is invoked.

    benchmark = mock()
    benchmark.expects(:measure).yields
    yielded = false
    benchmark.measure { yielded = true }
    yielded # => true

#####

Yield parameters when expected method is invoked.

    fibonacci = mock()
    fibonacci.expects(:next_pair).yields(0, 1)
    sum = 0
    fibonacci.next_pair { |first, second| sum = first + second }
    sum # => 1

#####

Yield different parameters on different invocations of the expected method.

    fibonacci = mock()
    fibonacci.expects(:next_pair).yields(0, 1).then.yields(1, 1)
    sum = 0
    fibonacci.next_pair { |first, second| sum = first + second }
    sum # => 1
    fibonacci.next_pair { |first, second| sum = first + second }
    sum # => 2

Parameters:

- parameters (`*Array`) —

  parameters to be yielded.

Returns:

- (`Expectation`) —

  the same expectation, thereby allowing invocations of other Mocha::Expectation methods to be chained.

See Also:

- #then

    402
    403
    404

    # File 'lib/mocha/expectation.rb', line 402

    def yields(*parameters)
      multiple_yields(parameters)
    end