I'd like to write something like this:
it 'does not invoke any MyService' do
MyService.should_not_receive(<any method>)
tested_method
end
I do not want to list all methods of MyService explicitly because this would lead to a brittle test that could give false positives silently if new methods were added to MyService.
How about replacing the implementation with a double?
it 'does not invoke any MyService' do
original_my_service = MyService
begin
# Replace MyService with a double.
MyService = double "should not receive any message"
tested_method
ensure
# Restore MyService to original implementation.
MyService = original_my_service
end
end
If methods in MyService are called, it should raise:
RSpec::Mocks::MockExpectationError: Double "should not receive any message" received unexpected message :some_method with (no args)
If you inject the MyService dependency inside your object, you can substitute it with a mock with no methods defined on it, so that any method call will raise an exception.
Let me show you an example:
class Manager
attr_reader :service
def initialize(service = MyService)
@service = service
end
def do_stuff
service.do_stuff
end
def tested_method
other_stuff
end
end
And the tests would be:
context "#do_stuff" do
let(:manager) { Manager.new }
it 'invokes MyService by default' do
MyService.should_receive(:do_stuff)
manager.do_stuff
end
end
context "#tested_method" do
let(:service) { mock("FakeService") }
let(:manager) { Manager.new(service) }
it 'does not invoke any service' do
expect { manager.tested_method }.not_to raise_error
end
end
it 'does not invoke MyService' do
stub_const('MyService', double)
tested_method
end
Any attempt to access MyService will return the mocked RSpec double. Since doubles raise errors when they receive messages that aren't explicitly stubbed (and none are being stubbed) any call to MyService will raise an error.
https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/basics/test-doubles
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With