我正在阅读 this教程。在“动态属性”部分中,它告诉您将您的 minitest 规范包装在一个 block 中,以检查覆盖的 method_missing 是否引发虚构属性的 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'
我在没有使用积木的情况下对其进行了测试,正如预期的那样,测试失败了。背后的原因是什么?
最佳答案
您将代码包装在 block 中,以便 expect
可以控制何时调用您的代码。在伪 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 - 为什么必须将对象属性包装在 block 中以检查它是否引发错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48929511/