【问题标题】:How do I test that a RuntimeError is using string interpolation correctly in Ruby?如何测试 RuntimeError 在 Ruby 中正确使用字符串插值?
【发布时间】:2019-06-15 06:00:24
【问题描述】:

我有一个方法可以记录对数据库中特定记录的更改,但首先,它会在继续之前检查类别类型的有效性。如果返回 false,则会引发错误。

class UpgradePackageRecorder

  CATEGORIES = [ an array of categories here ... ]

  def initialize(category)
    @category = category
  end

  def record_change
    unless valid_category?
      raise "#{category} is not a recognized category"
    end

    other_methods
  end

  private

  def valid_category?
    CATEGORIES.include?(category)
  end

end

我开始为此编写一个 rspec 测试,以验证错误是否正确引发。这是测试用例:

RSpec.describe UpgradePackageRecorder do
  describe '#record_change' do
    context 'the package type is invalid' do
      it 'raises an error' do

       recorder = UpgradePackageRecorder.new('Bronze')

       expect { recorder.record_change }.to raise_error(RuntimeError, /bronze is not a recognized category/)
      end
    end
  end
end

当我运行测试时,我得到了这个错误:

Failure/Error: raise "#{category} is not a recognized category"

RuntimeError:
  bronze is not a recognized category

为什么字符串插值会这样显示?我也试过了 category + ' is not a recognized category 但这并没有解决问题。

为了让这更令人困惑,我取出了字符串插值,但仍然看到了问题:

Failure/Error: raise "Unrecognized category"

RuntimeError:
  Unrecognized category

【问题讨论】:

  • 看起来错误没有被expect { change } 拦截...你能显示模型回调(如何调用valid_category?)和整个rspec caseq
  • 我更新了更详尽的示例。
  • Bronzebronze 不一样。那么CATEGORIES 呢?可能问题是该数组包含您的类别吗?
  • @mechnicov 我忘了包括我在 UpgradePackageRecorder 中有一个方法,当它们到达那里时,它会降低所有类别。另外,我仔细检查了类别数组不包括“青铜”。

标签: ruby-on-rails ruby unit-testing error-handling rspec


【解决方案1】:

我想通了!

最终为我工作的语法是这样的:

it 'raises an error' do

  expect do
    UpgradePackageRecorder.new(
      'Bronze'
    ).record_change
  end.to raise_error(
    RuntimeError, /bronze is not a recognized category/
  )

end

此外,我在删除的同一 it 块中还有另一个 expect。它正在验证record_change 方法是否继续创建某个对象。

【讨论】:

  • "正在验证 record_change 方法是否继续创建某个对象。" - 好吧,that 是问题所在,而不是花括号与 do/end。无论如何,很好地解决这个问题。
  • 你应该分开测试,所以subject { described_class.new('Bronze') }可以放在上下文级别,然后你可以在同一个对象上指定不同的东西,在单独的it块中。
猜你喜欢
  • 2023-03-31
  • 2022-12-22
  • 2013-08-14
  • 2017-01-28
  • 2014-01-09
  • 1970-01-01
  • 2011-01-04
  • 2011-11-15
  • 2011-01-15
相关资源
最近更新 更多