Reputation: 2949
I have a piece of code that retries a certain API call 3 times before failing. I also have a stub for this API.
I want to write two tests in the case of failure:
Here is the first test:
it 'fails' do
expect { risky_call } to raise_error SomeError
end
The second test however, is a bit trickier:
it 'calls the API three times' do
risky_call
expect(stub).to have_been_requested.times(3)
end
The problem is that risky_call
raises SomeError
, making the test fail. I thought of doing something like this:
it 'calls the API three times' do
risky_call rescue nil
expect(stub).to have_been_requested.times(3)
end
But it does seem very hackish.
Is there a better/safer/more idiomatic way to write this spec?
Upvotes: 0
Views: 267
Reputation: 29403
Not sure what your stub looks like but this appears to be one of those times where the single expectation per test rule need not apply.
Your specification is very clear it should try 3 times before raising an error so a test like
it 'calls the API three times before raising an error' do
expect { risky_call }.to raise_error(SomeError)
expect(stub).to have_been_requested.times(3)
end
Makes logical sense to me. Expecting it to "call 3 times" without context does not. What if it only calls 1 time or 2 times? This makes your test description misleading. The new description explains that it will retry 3 times before an error is raised which is what you actually meant and is easy to understand.
Upvotes: 1