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
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
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)