【问题标题】:How can I check if my subject raises an exception?如何检查我的主题是否引发异常?
【发布时间】:2014-07-27 18:02:49
【问题描述】:

我目前正在subject 中创建一个对象,需要测试这是否引发异常。以下代码说明了我想要实现的目标:

describe MyClass do
  describe '#initialize' do
    subject { MyClass.new }

    it { is_expected.not_to raise_error(Some::Error) }
  end
end

我感觉我做错了。将subject 设置为新对象而不创建对象两次的首选方法是什么?


更新

我的问题有两个方面。首先,这种语法不起作用:

it { is_expected.not_to raise_error }

it 块内使用 expect 可以,但是(正如 Jimmy Cuadra 所指出的):

it 'does not raise an error' do
  expect { subject }.not_to raise_error
end

我对 RSpec 不够熟悉,无法告诉你这是为什么。

其次,由于RSpec 3.0.0.beta1,可以再将raise_error 与特定的错误类一起使用。因此,以下内容无效:

expect { subject }.to raise_error(Some::Error)

有关详细信息,请参阅

【问题讨论】:

  • 你有一个implicit subject,所以你不需要subject { MyClass.new }
  • 很容易知道,@ArupRakshit!尽管我的简化示例中的构造函数不带参数,但我的实际类中的构造函数却带参数。

标签: ruby rspec rspec3


【解决方案1】:

如果我理解正确,您正在尝试测试实例化类是否会导致异常。您只需这样做:

describe MyClass do
  it "doesn't raise an exception when instantiated" do
    expect { subject }.not_to raise_error
  end
end 

【讨论】:

  • 我接受这个,因为它确实是我问题的答案。我已经更新了这个问题,以防其他人有类似的问题,因为还有另一个问题。
  • 这里的关键是您需要将subject 放在expect 块内。你不能使用it { is_expected.not_to raise_error },你可以使用expect { subject.not_to raise_error }。您需要使用expect { subject }.not_to raise_error。为这里的答案干杯。
【解决方案2】:

通过is_expected 语法做到这一点的正确方法是用 Proc 包装您的主题值,如下例所示:

describe MyClass do
  describe '#initialize' do
    subject { -> { MyClass.new } }
    it      { is_expected.not_to raise_error(Some::Error) }
  end
end

这种方式更准确,因为有时您的用例是期望不应抛出特定类型的异常(而允许抛出其他异常)。这种方法将涵盖此类用例。

【讨论】:

  • 是的,确实如此。只要确保你的 RSpec 版本支持is_expected 方法。
  • 看起来它只是检查 Proc 对象是否引发异常?
  • @OlegAfanasyev 是的。基本上raise_error 将在内部调用.call 上由subject 存储/返回的.call
  • @leandroico,我在源代码中没有找到任何 .call 调用,也没有任何意义为评估到 procs 的主题制定特殊情况,因为主题已经包含在 @ 987654329@ 块,直到测试运行时才被调用。
  • @OlegAfanasyev 我相信这种基于 Proc 的行为来自raise_error,而不是其他东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多