Richard-Degenne
Richard-Degenne

Reputation: 2949

How to test stubs in failing code?

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

Answers (1)

engineersmnky
engineersmnky

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

Related Questions