Module: Mocha::API

Includes:
Hooks, ParameterMatchers
Included in:
Integration::Minitest::Adapter, Integration::TestUnit::Adapter
Defined in:
lib/mocha/api.rb

Overview

Methods added to Test::Unit::TestCase, Minitest::Unit::TestCase or equivalent. The mock creation methods are #mock, #stub and #stub_everything, all of which return a #Mock which can be further modified by Mock#responds_like and Mock#responds_like_instance_of methods, both of which return a Mock, too, and can therefore, be chained to the original creation methods.

Mock#responds_like and Mock#responds_like_instance_of force the mock to indicate what it is supposed to be mocking, thus making it a safer verifying mock. They check that the underlying responder will actually respond to the methods being stubbed, throwing a NoMethodError upon invocation otherwise.

Examples:

Verifying mock using Mock#responds_like_instance_of

class Sheep
  def initialize
    raise "some awkward code we don't want to call"
  end
  def chew(grass); end
end

sheep = mock('sheep').responds_like_instance_of(Sheep)
sheep.expects(:chew)
sheep.expects(:foo)
sheep.respond_to?(:chew) # => true
sheep.respond_to?(:foo) # => false
sheep.chew
sheep.foo # => raises NoMethodError exception

Instance Method Summary collapse

Methods included from Hooks

#mocha_setup, #mocha_teardown, #mocha_test_name, #mocha_verify

Methods included from ParameterMatchers

#Not, #all_of, #any_of, #any_parameters, #anything, #equals, #equivalent_uri, #has_entries, #has_entry, #has_key, #has_keys, #has_value, #includes, #instance_of, #is_a, #kind_of, #optionally, #regexp_matches, #responds_with, #yaml_equivalent

Instance Method Details

#mock(name) ⇒ Mock #mock(expected_methods_vs_return_values = {}) ⇒ Mock #mock(name, expected_methods_vs_return_values = {}) ⇒ Mock

Builds a new mock object

Examples:

Using expected_methods_vs_return_values Hash to setup expectations.

def test_motor_starts_and_stops
  motor = mock('motor', start: true, stop: true)
  assert motor.start
  assert motor.stop
  # an error will be raised unless both Motor#start and Motor#stop have been called
end

Overloads:

  • #mock(name) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

  • #mock(expected_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • expected_methods_vs_return_values (Hash) (defaults to: {})

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

  • #mock(name, expected_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

    • expected_methods_vs_return_values (Hash) (defaults to: {})

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

Returns:

  • (Mock)

    a new mock object



69
70
71
72
73
74
75
# File 'lib/mocha/api.rb', line 69

def mock(*arguments)
  name = arguments.shift.to_s if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol)
  expectations = arguments.shift || {}
  mock = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock
  mock.expects(expectations)
  mock
end

#sequence(name) { ... } ⇒ Sequence

Builds a new sequence which can be used to constrain the order in which expectations can occur.

Specify that an expected invocation must occur within a named Sequence by calling Expectation#in_sequence on each expectation or by passing a block within which all expectations should be constrained by the Sequence.

Examples:

Ensure methods on egg are invoked in correct 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)

Ensure methods across multiple objects are invoked in correct order.

sequence = sequence(:task_order)

task_one = mock("task_one")
task_two = mock("task_two")

task_one.expects(:execute).in_sequence(sequence)
task_two.expects(:execute).in_sequence(sequence)

task_one.execute
task_two.execute

Ensure methods on egg are invoked in the correct order using a block.

egg = mock('egg')
sequence('breakfast') do
  egg.expects(:crack)
  egg.expects(:fry)
  egg.expects(:eat)
end

Parameters:

  • name (String)

    name of sequence

Yields:

  • optional block within which expectations should be constrained by the sequence

Returns:

See Also:



170
171
172
173
174
175
176
177
178
179
# File 'lib/mocha/api.rb', line 170

def sequence(name)
  Sequence.new(name).tap do |seq|
    Mockery.instance.sequences.push(seq)
    begin
      yield if block_given?
    ensure
      Mockery.instance.sequences.pop
    end
  end
end

#states(name) ⇒ StateMachine

Builds a new state machine which can be used to constrain the order in which expectations can occur.

Specify the initial state of the state machine by using StateMachine#starts_as.

Specify that an expected invocation should change the state of the state machine by using Expectation#then.

Specify that an expected invocation should be constrained to occur within a particular state by using Expectation#when.

A test can contain multiple state machines.

Examples:

Constrain expected invocations to occur in particular states.

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:

  • name (String)

    name of state machine

Returns:

See Also:



207
208
209
# File 'lib/mocha/api.rb', line 207

def states(name)
  Mockery.instance.new_state_machine(name)
end

#stub(name) ⇒ Mock #stub(stubbed_methods_vs_return_values = {}) ⇒ Mock #stub(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

Builds a new mock object

Examples:

Using stubbed_methods_vs_return_values Hash to setup stubbed methods.

def test_motor_starts_and_stops
  motor = stub('motor', start: true, stop: true)
  assert motor.start
  assert motor.stop
  # an error will not be raised even if either Motor#start or Motor#stop has not been called
end

Overloads:

  • #stub(name) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

  • #stub(stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

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

  • #stub(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

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

Returns:

  • (Mock)

    a new mock object



96
97
98
99
100
101
102
# File 'lib/mocha/api.rb', line 96

def stub(*arguments)
  name = arguments.shift.to_s if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol)
  expectations = arguments.shift || {}
  stub = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock
  stub.stubs(expectations)
  stub
end

#stub_everything(name) ⇒ Mock #stub_everything(stubbed_methods_vs_return_values = {}) ⇒ Mock #stub_everything(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

Builds a mock object that accepts calls to any method. By default it will return nil for any method call.

Examples:

Ignore invocations of irrelevant methods.

def test_motor_stops
  motor = stub_everything('motor', stop: true)
  assert_nil motor.irrelevant_method_1 # => no error raised
  assert_nil motor.irrelevant_method_2 # => no error raised
  assert motor.stop
end

Overloads:

  • #stub_everything(name) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

  • #stub_everything(stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

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

  • #stub_everything(name, stubbed_methods_vs_return_values = {}) ⇒ Mock

    Parameters:

    • name (String, Symbol)

      identifies mock object in error messages.

    • stubbed_methods_vs_return_values (Hash) (defaults to: {})

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

Returns:

  • (Mock)

    a new mock object



123
124
125
126
127
128
129
130
# File 'lib/mocha/api.rb', line 123

def stub_everything(*arguments)
  name = arguments.shift if arguments.first.is_a?(String) || arguments.first.is_a?(Symbol)
  expectations = arguments.shift || {}
  stub = name ? Mockery.instance.named_mock(name) : Mockery.instance.unnamed_mock
  stub.stub_everything
  stub.stubs(expectations)
  stub
end