我目前正在阅读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/