如何在没有无限循环的情况下测试方法重试乐观锁定?

时间:2013-08-20 18:20:58

标签: ruby rspec

我正在使用乐观锁定,当更新我的对象失败时,我的目标是重试查询,直到它通过。我的问题是救援部分从未用于rspec测试。

我正在讨论的方法如下:

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 

StaleObjectError是在transaction.save!上生成的,它有一个before_create挂钩,用于编辑其他对象(在这种情况下,从对象帐户中删除钱)。

为了测试它,我可以,例如,存根Transaction.new来引发StaleObjectError,但它会产生一个无限循环。

我也无法用像

这样的方法进行测试
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

因为我没有测试before_save钩子,所以我正在测试create_transaction方法。 (感谢@screenmutt的例子)

如何正确测试救援部分?

2 个答案:

答案 0 :(得分:1)

首先,创建对象时会引发StaleObjectError 。编辑时可能会引发此问题。 See the Docs

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

测试救援块

这就是存根的用途,从你通常看不到的方法中返回一个特定的值。

您还可以存根save!

RSpec Simple Stub Documentation

答案 1 :(得分:0)

我需要能够测试的答案是this answer by Chris Heald中引用的unstub方法