Difference between Mocks and Stubs in RSpec
What is the difference, how and when to apply?
Stub
A stub is the only defined result of the method call which doesn’t care about behavior. With RSpec, you can use stub with allow
and receive
methods.
allow(object).to receive(:method_name)
If you need to stub the result of the method then it’s possible with and_return
allow(object).to receive(:method_name).and_return(example_value)
Mock
Mock expect methods to be called, otherwise it raises an error. With RSpec, you can use mock with expect
and receive
methods.
expect(object).to receive(:method_name)
As well as the stub replacing mock result possible with and_return
expect(object).to receive(:method_name).and_return(example_value)
Double
Test double is a dummy object that you use to replace a real object during a test. Through RSpec, you can create it with the double
method.
describe UpdateObject do
let(:external_api) { double } before do
allow(ExternalApi).to recieve(:new).and_return(external_api)
allow(external_api).to recieve(:some_api_call)
end it 'returns success' do
expect(subject.call).to eq(:success)
end
end
In the example above we are using fake double
object created to replace API call inside UpdateObject
and avoid dependence of the test on the work of an external service.
If you want to create a more specified test, you can replace double
with instance_double
, which will fail tests if the class or object doesn’t have used methods.