When testing the outcome of nested rollbacks, we explicitly told a class to receive(:end!).and_raise(ActiveRecord::RecordNotSaved) to emulate a deep failure in our transactions.
While testing, RSpec would raise this error during the test causing a test failure.
To remedy this we added a rescue and raise to the parent method and all was fine with the world.
def update_current_thing!(thing)
transaction do
other_things.each(&:end!)
end
rescue
raise ActiveRecord::Rollback
end
However, when looking at this code, and another similar instance of it, we thought that Rails should really handle this for us. Queue the refactor π§.
First, we removed the smelly code and saw our test suite fail again π€. Enter the investigation phase.
The investigation started as no more than a hunch that this code should work as expected, without the explicit raise, as per the Rails documentation
The investigation led to a blog post discussing the very same issue, with the solution of wrapping the expectation in a suppress block.
Suppressing the errors stops RSpec from failing due to the error and instead allows the rest of the test to be executed.
suppress(ActiveRecord::RecordNotSaved) do
thing.update_current_thing!(other_thing)
end
expect(thing.current_thing).to eq(other_thing)