Rails ActiveSupport:如何断言引发了错误?

Posted

技术标签:

【中文标题】Rails ActiveSupport:如何断言引发了错误?【英文标题】:Rails ActiveSupport: How to assert that an error is raised? 【发布时间】:2011-03-28 03:55:25 【问题描述】:

我想在我的一个模型上测试一个会引发特定错误的函数。该函数看起来像这样:

def merge(release_to_delete)
  raise "Can't merge a release with itself!" if( self.id == release_to_delete.id )
  raise "Can only merge releases by the same artist" if( self.artist != release_to_delete.artist   )
  #actual merge code here
end

现在我想做一个断言,当我使用导致每个异常的参数调用此函数时,异常实际上会被抛出。我正在查看 ActiveSupport 文档,但没有发现任何有希望的东西。有什么想法吗?

【问题讨论】:

【参考方案1】:

所以单元测试并没有真正得到积极的支持。 Ruby 在标准库中带有一个典型的 xunit 框架(ruby 1.8.x 中的 Test::Unit,ruby 1.9 中的 MiniTest),而 activesupport 中的东西只是添加了一些东西。

如果你正在使用 Test::Unit/MiniTest

assert_raise(Exception)  whatever.merge 

如果您使用的是 rspec(不幸的是,文档记录不佳,但更受欢迎)

lambda  whatever.merge .should raise_error

如果你想检查提出的Exception

exception = assert_raises(Exception)  whatever.merge 
assert_equal( "message", exception.message )

【讨论】:

谢谢!我不得不使用“RuntimeError”而不是异常,例如:assert_raise(RuntimeError) artist1.merge(artist1) 本指南非常有帮助:guides.rubyonrails.org/testing.html @spiilliton:那是因为 Ruby 解释器将上面的代码视为assert_raise(Exception() whatever.merge ),即它寻找一个名为Exception 的方法,该方法使用给定的块调用。添加括号 解决了这种歧义。 (已经确定了答案) 在 rspec 3 中,使用 expect whatever.merge .to raise_error (relishapp.com/rspec/rspec-expectations/v/3-1/docs/…)【参考方案2】:

为了确保在您的测试用例中不会引发(或成功处理)异常:

assert_nothing_raised RuntimeError do
  whatever.merge
end

要检查是否引发了错误,请在测试用例中执行:

assert_raise RuntimeError do
  whatever.merge
end

请注意,whatever.merge 是引发错误的代码(或不引发错误,取决于断言类型)。

【讨论】:

以上是关于Rails ActiveSupport:如何断言引发了错误?的主要内容,如果未能解决你的问题,请参考以下文章

Rails:我如何需要 ActiveSupport 的rescue_from 方法?

带 ActiveSupport 的默认时区(不带 Rails)

如何使用 NSTimeZone -timeZoneWithName: 与 Rails ActiveSupport 中的城市名称?

使用 Ruby on Rails ActiveSupport::Concern 功能时如何“嵌​​套”包含模块?

rails activesupport 通知 - 错误的数据库运行时值

在 Rails 中,如何以可与 ActiveSupport::TimeZone[zone].parse() 一起使用的格式获取当前时区 (Time.zone)?