我正在尝试为rspec的扩展编写规范。
这是我要测试的要点:
require 'rspec-let-and-after-extension'
RSpec.describe "let(...).and_after" do
it 'is called if the `let` is invoked even if the example fails' do
call_order = []
RSpec.describe do
let(:foo) { }.and_after { call_order << :and_after }
it { foo; call_order << :example; raise 'failed!' }
end.run
expect(call_order).to eq [:example, :and_after]
end
end
一个重要的行为是,如果运行示例失败,清理代码仍然运行。因此,我通过记录调用的顺序并从示例中引发一个异常来测试这一点。
问题是,当我运行它时,它将此块视为第二个示例,然后失败并出现错误:
.F
Failures:
1)
Got 0 failures and 2 other errors:
1.1) Failure/Error: it { foo; call_order << :example; raise 'failed!' }
RuntimeError:
failed!
# ./spec/spec.rb:43:in `block (4 levels) in <top (required)>'
# ./spec/spec.rb:44:in `block (2 levels) in <top (required)>'
1.2) Failure/Error: it { foo; call_order << :example; raise 'failed!' }
RuntimeError:
failed!
# ./spec/spec.rb:43:in `block (4 levels) in <top (required)>'
Finished in 0.00167 seconds (files took 0.08011 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/spec.rb:43 #
如您所见,输出确实有一个点,因此实际示例传递的是。但是有一个F,因为它已经看到了内部的例子,运行它,不出所料,一个失败了。
我如何使rspec不把这个嵌套的例子看作是它应该运行的例子之一,这样这个例子就完成了一个点?
(如果您想知道rspec开发人员自己对他们的测试做了什么,看起来他们使用的是cucumber。他们用黄瓜是因为他们也弄不明白吗?:))
您可以使用新的沙箱API(在3.2+中可用)。
RSpec.configure do |rspec|
rspec.around do |ex|
RSpec::Core::Sandbox.sandboxed do |config|
# re-configure any configuration defined by your extension here
# before allowing the example to run. The sandbox runs with a fresh
# config instance, which means any configuration you have set in
# `rspec-let-and-after-extension` will not apply while the example
# is running.
# config.extend MyExtensionModule
ex.run
end
end
end