我目前正在阅读this教程在“动态属性”部分中,它告诉您将minitest规范包装在一个块中,以检查是否覆盖缺少的方法会在虚构属性上引发NoMethodError我用的是RSpec,docs显示的是完全相同的模式:

RSpec.describe "calling a missing method" do
  it "raises" do
    expect { Object.new.foo }.to raise_error(NameError)
  end
end

我的规格:
合格规格
it "raises a method missing error if attribute is not present" do
  expect { coin.imaginary_attribute }.to raise_error(NoMethodError)
end

不合格规格
it "raises a method missing error if attribute is not present" do
  expect(coin.imaginary_attribute).to raise_error(NoMethodError)
end

错误消息:
NoMethodError:
      undefined method `imaginary_attribute'

我在没有使用块的情况下测试了它,正如预期的那样,测试失败了背后的原因是什么?

最佳答案

将代码包装在块中,以便expect可以控制何时调用代码在pseudo ruby中,它看起来像这样:

def expect(&block)
  begin
    block.call
  rescue => ex
    save_exception_for_assertions(ex)
  end
end

这可以做两件事:
拦截异常,以便匹配者可以使用它
确保异常不会影响规范的执行(因为它是预期的)。
相比之下,你尝试的另一种变体
 expect(coin.imaginary_attribute).to raise_error(NoMethodError)

coin.imaginary_attribute是在调用expect之前计算的(因为这里它是方法调用中的常规参数)。因此expect没有机会截获异常,您的规范将崩溃。

关于ruby - 为什么必须将对象属性包装在块中以检查是否引发错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48929511/

10-13 02:18