Ruby on rails Rspec:如何测试重试?
我已经为比赛条件实现了乐观锁定。如果Ruby on rails Rspec:如何测试重试?,ruby-on-rails,ruby,ruby-on-rails-3,rspec,rspec-rails,Ruby On Rails,Ruby,Ruby On Rails 3,Rspec,Rspec Rails,我已经为比赛条件实现了乐观锁定。如果lock\u版本与数据库中更新的lock\u版本不匹配,则将触发重试三次。您能否建议如何测试此重试事件 #Product: Model's new field: # lock_version :integer(4) default(0), not null def recalculate method_1 self.save! end private def method_1
lock\u版本
与数据库中更新的lock\u版本
不匹配,则将触发重试
三次。您能否建议如何测试此重试事件
#Product: Model's new field:
# lock_version :integer(4) default(0), not null
def recalculate
method_1
self.save!
end
private
def method_1
begin
####
####
if self.lock_version == Product.find(self.id).lock_version
Product.where(:id => self.id).update_all(attributes)
else
raise ActiveRecord::StaleObjectError.new(self, "test")
end
rescue ActiveRecord::StaleObjectError => e
if tries < 3
tries += 1
sleep(1 + tries)
self.reload
retry
else
raise Exception.new(timeout.inspect)
end
end
end
首先,我要把你的方法的复杂性分解成这样
private
def stale_object?
self.lock_version == Product.find(self.id).lock_version
end
def attempt_to_rescue_stale_object
if rescue_stale_object_retries =< 3
rescue_stale_object_retries += 1
sleep( 1 + rescue_stale_object_retries)
retry # and the sleep stuff, not sure how you
else
raise Exception.new(timeout.inspect)
end
end
def rescue_stale_object_retries
@rescue_stale_object_retries ||= 0
end
def method_1
begin
raise ActiveRecord::StaleObjectError.new(self, "test") if stale_object?
Product.where(:id => self.id).update_all(attributes)
rescue ActiveRecord::StaleObjectError => e
attempt_to_rescue_stale_object
reload # You can omit the self here
else
raise Exception.new(timeout.inspect)
end
end
end
将复杂性分解为小部分的另一个好处是,您的意图可以更好地传达给您的开发伙伴(另一个人或您在6个月后忘记了初始测试目标)您可以模拟sleep
方法,并计数检查是否使用连续值2、3调用它,4.@WizadoFogz您能建议如何测试连续值2、3、4吗尝试方法1中未定义(将引发名称错误)即使我假设它是在######
的位置定义的,它也会在每次重试时重置,从而破坏整个目的,除非您使用|124;=
我猜可能重复的错误无效重试
。看起来Begin/Rescue块是使用Retry now的唯一方法。哦,糟糕的是,我将Retry视为伪代码而不是关键字。它需要一些返工才能正常运行
private
def stale_object?
self.lock_version == Product.find(self.id).lock_version
end
def attempt_to_rescue_stale_object
if rescue_stale_object_retries =< 3
rescue_stale_object_retries += 1
sleep( 1 + rescue_stale_object_retries)
retry # and the sleep stuff, not sure how you
else
raise Exception.new(timeout.inspect)
end
end
def rescue_stale_object_retries
@rescue_stale_object_retries ||= 0
end
def method_1
begin
raise ActiveRecord::StaleObjectError.new(self, "test") if stale_object?
Product.where(:id => self.id).update_all(attributes)
rescue ActiveRecord::StaleObjectError => e
attempt_to_rescue_stale_object
reload # You can omit the self here
else
raise Exception.new(timeout.inspect)
end
end
end
expect{car_v2}.to receive(:attempt_to_rescue_stale_object).exactly(3).times
car_v2.method1