Spying is used to assert if a method has been called, here we will see how to use spies with Rspec.

Spies are similar to mock in the way that both assert if a method was called. But they are different in many ways. One difference is that mocks have the assert before the action, while spies have action before assert. Hence spies follow the Arrange-Act-Assert pattern which make tests easy to read and understand.

In Rspec, you just call spy to create a spy object. Here is a simple (but realistic) example of how to use spies with rspec:

class PushNotificationService
  def initialize(notifier, message)
    @notifier = notifier
    @message = message
  end

  def call
    @notifier.notify(@message)
  end
end

RSpec.describe 'PushNotificationService' do
  it 'calls sends pushnotification to the notifier' do
    notifier = spy # this can be the platform-specific library (android/ios etc.)
    message = 'Test Message'
    service = PushNotificationService.new(notifier, message)

    service.call

    expect(notifier).to have_received(:notify).with(message)
  end
end

Notice that the example has three distinct sections Arrange - Act - Assert.

References: