Rspec:如何测试在私有方法中引发的异常?



在我的公共方法 #recalculate 中,调用私有method1。此方法引发异常"ActiveRecord::StaleObjectError"。

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

Rspec 测试用例:

it 'if car is updated then ActiveRecord::StaleObjectError should be raised' do
prod_v1 =Product.find(@prod.id)
prod_v2 = Car.find(@prod.id)
prod_v1.recalculate
prod_v1.reload  # will make lock_version of prod_v1 to 1
prod_v2.recalculate # howvever lock_version of prod_v2 is still 0.
expect{ prod_v2.send(:method1)}.to raise_error(ActiveRecord::StaleObjectError)

错误:

Failure/Error: expect(prod_v2.send(:method1((.to raise_error(ActiveRecord::StaleObjectError( 预期的活动记录::StaleObjectError 但没有任何引发

请建议如何为私有方法中引发的异常编写单元测试用例。 我根据链接使用了send

注意:第一次引发异常,因为 == Product.find(self.id( 为假self.lock_version。在重试中self.lock_version == Product.find(self.id( 为真,因此不会捕获异常。

下面是代码实际执行的操作的更简单版本:

class StaleObjectError < Exception
end
class MyClass
def initialize
@tries = 0
end
def method_1
begin
raise StaleObjectError.new("I'm the more specific exception")
rescue StaleObjectError => e
if @tries < 3
@tries += 1
sleep(1 + @tries)
retry
else
raise Exception.new("I'm the failure case")
end
end
end
end
myObject = MyClass.new
begin
myObject.method_1
rescue Exception => e
# in the error condition, this is always #<Exception: I'm the failure case>
puts e.inspect
end

这导致

#<Exception: I'm the failure case>

您将无法期望ActiveRecord::StaleObjectError,因为您用救援方式掩盖了它 - 您已经将StaleObjectError转换为Exception

如果你想保留StaleObjectError那么你可以raise e你的救援。因此,再次使用我的示例代码:

if @tries < 3
@tries += 1
sleep(1 + @tries)
retry
else
raise e
end

这将导致

#<StaleObjectError: I'm the more specific exception>

然后,您的 rspec 示例应该能够期望代码引发正确的异常类型。

相关内容

  • 没有找到相关文章

最新更新