Obromios
Obromios

Reputation: 16393

How to use rspec to test a transaction block

I am wrapping some code in a transaction block i.e.

Tip.transaction do
  ...make changes to lots of tips...
end

The reason I am doing this is I want to make sure all the changes are made before being committed to the database. How do I use rspec to test that if a failure occurs before the transaction is completed, then the database will rollback to its previous state?

Upvotes: 3

Views: 2819

Answers (1)

dgilperez
dgilperez

Reputation: 10796

You can just check that no Tip was persisted to the in case of failure. The only doubt here is what does a failing tip means for you, since that's what you will reproduce in your test. A plain vanilla example:

# app/models/tip.rb
before_save :fail_if_bad_amoun
def fail_if_bad_amount
  fail BadAmount if amount == 'bad'
end

def self.process(tips)
  Tip.transaction do
    tips.all? &:save
  end
end

# spec/models/tip_spec.rb
it "does not commit in case of failure in one of the tips" do
  good_tip = Tip.new(amount: 1_000)
  bad_tip  = Tip.new(amount: 'bad')

  expect do
    Tip.process([good_tip, bad_tip])
  end.not_to change { Tip.count }
end

Upvotes: 2

Related Questions