I'm trying to implement a method that retries to save a record into the database when this exception is raised.
Then, I'm trying to create a scenario where the first save call raises that exception and the second one returns true and persists the record.
Your environment
Ruby version: 2.6.5
rspec-mocks version: 3.7.0
Steps to reproduce
require 'rspec'
DatabaseError = Class.new(RuntimeError)
class Foo
ATTEMPTS = 2
def bar
@attempt ||= 1
baz
rescue DatabaseError
if @attempt <= attempts
@attempt += 1
retry
else
# Do Something to finsh attempts
end
end
def baz
# Database Call Which can raise an error
nil
end
end
RSpec.describe Foo do
describe '#bar' do
subject(:foo) { described_class.new }
context 'trying with 2 allows' do
before do
allow(foo).to receive(:baz).and_raise(DatabaseError)
allow(foo).to receive(:baz).and_return(true)
end
it 'retries the operation' do
expect(foo).to receive(:baz).exactly(2).times
foo.bar
end
end
context 'trying with just one allow' do
before do
allow(foo).to receive(:baz).and_raise(DatabaseError).and_return(true)
end
it 'retries the operation' do
expect(foo).to receive(:baz).exactly(2).times
foo.bar
end
end
end
end
RSpec::ExampleGroups::Foo.run(RSpec.configuration.reporter)
Expected behavior
The test pass with the method #baz being called 2 times.
Actual behavior
Test break because just the mock that returns true is executed.
Subject of the issue
I'm trying to implement a method that retries to save a record into the database when this exception is raised. Then, I'm trying to create a scenario where the first save call raises that exception and the second one returns true and persists the record.
Your environment
Steps to reproduce
Expected behavior
The test pass with the method
#baz
being called 2 times.Actual behavior
Test break because just the mock that returns
true
is executed.