I'm using optimistic locking, and when there is a failure on updating my object, I aim to retry the query until it passes. My problem is that the rescue section is never used on the rspec tests.
The method I'm talking about is the following:
def create_transaction
amount = -1 * cost_per_word * word_count
transaction = Transaction.new(amount: amount, processor: :job_done)
transaction.service = service
transaction.job = self
transaction.save!
rescue ActiveRecord::StaleObjectError
sleep rand
reload
retry
end
The StaleObjectError is generated on transaction.save!
, which have a before_create
hook which edits other object (in this case, removing money from the object account).
To test it, I could, for example, stub Transaction.new
to raise an StaleObjectError
, however it would generate an infinite loop.
I also can't test with an approach like
p1 = Person.find(1)
p2 = Person.find(1)
p1.first_name = "Michael"
p1.save
p2.first_name = "should fail"
p2.save # Raises a ActiveRecord::StaleObjectError
Because I'm not testing the before_save
hook, I'm testing the create_transaction
method. (thanks to @screenmutt for the example)
How can I properly test the rescue section?