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)