Module: Cuprum::Utils::InstanceSpy

Defined in:
lib/cuprum/utils/instance_spy.rb

Overview

Instruments calls to the #call method of any instance of a command class.

This can be used to unobtrusively test the functionality of code that calls a command without providing a reference to the command instance, such methods that create and call a command instance.

Examples:

Observing calls to instances of a command.

spy = Cuprum::Utils::InstanceSpy.spy_on(CustomCommand)

allow(spy).to receive(:call)

CustomCommand.new.call(1, 2, 3, :four => '4')

expect(spy).to have_received(:call).with(1, 2, 3, :four => '4')

Block syntax

Cuprum::Utils::InstanceSpy.spy_on(CustomCommand) do |spy|
  allow(spy).to receive(:call)

  CustomCommand.new.call

  expect(spy).to have_received(:call)
end

Defined Under Namespace

Classes: Spy

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.clear_spiesObject

Retires all spies.

Subsequent calls to the #call method on command instances will not be mirrored to existing spy objects.



41
42
43
44
45
# File 'lib/cuprum/utils/instance_spy.rb', line 41

def clear_spies
  Thread.current[:cuprum_instance_spies] = nil

  nil
end

.spy_on(command_class) ⇒ Cuprum::Utils::InstanceSpy::Spy .spy_on(command_class) {|Cuprum::Utils::InstanceSpy::Spy| ... } ⇒ nil

Note:

Calling this method for the first time will prepend the Cuprum::Utils::InstanceSpy module to Cuprum::Command.

Finds or creates a spy object for the given module or class.

Each time that the #call method is called for an object of the given type, the spy’s #call method will be invoked with the same arguments and block.

Overloads:

Parameters:

  • command_class (Class, Module)

    The type of command to spy on. Must be either a Module, or a Class that extends Cuprum::Command.

Raises:

  • (ArgumentError)

    If the argument is neither a Module nor a Class that extends Cuprum::Command.



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/cuprum/utils/instance_spy.rb', line 71

def spy_on(command_class)
  guard_spy_class!(command_class)

  instrument_call!

  if block_given?
    instance_spy = assign_spy(command_class)

    yield instance_spy
  else
    assign_spy(command_class)
  end
end

Instance Method Details

#call(*arguments, **keywords) { ... } ⇒ Cuprum::Result

Executes the command and returns a Cuprum::Result or compatible object.

Each time #call is invoked, the object performs the following steps:

  1. The #process method is called, passing the arguments, keywords, and block that were passed to #call.

  2. If the value returned by #process is a Cuprum::Result or compatible object, that result is directly returned by #call.

  3. Otherwise, the value returned by #process will be wrapped in a successful result, which will be returned by #call.

Parameters:

  • arguments (Array)

    Arguments to be passed to the implementation.

  • keywords (Hash)

    Keywords to be passed to the implementation.

Yields:

  • If a block argument is given, it will be passed to the implementation.

Returns:



130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/cuprum/utils/instance_spy.rb', line 130

def call(*args, **kwargs, &block)
  if kwargs.empty?
    Cuprum::Utils::InstanceSpy.send(:call_spies_for, self, *args, &block)
  else
    # :nocov:
    Cuprum::Utils::InstanceSpy
      .send(:call_spies_for, self, *args, **kwargs, &block)
    # :nocov:
  end

  super
end