G G*_*III 7 ruby rspec ruby-on-rails
为了避免在我的Rspec测试中重复自己,我想编写一个这样的函数
def with_each_partner(&block)
PARTNER_LIST.each do |partner|
context "with partner #{partner.name}" { yield partner }
end
end
Run Code Online (Sandbox Code Playgroud)
我有这样一个功能,它的工作原理是所有测试都使用正确的值提供给合作伙伴,但是在输出过程中它们不会作为"with partner X"上下文的一部分打印:相反,如果我有一个测试像这样:
describe Thing do
subject { Thing.new(partner) }
with_each_partner do |partner|
it 'does its thing' do
expect(subject.do).to eq 'its thing'
end
end
end
Run Code Online (Sandbox Code Playgroud)
我最终得到这样的输出:
Thing
does its thing
Run Code Online (Sandbox Code Playgroud)
而不是所需的输出,如:
Thing
with partner X
does its thing
with partner Y
does its thing
Run Code Online (Sandbox Code Playgroud)
如何让RSpec正确使用我函数中创建的上下文?
TL; DR:这样做:
def with_each_partner(&block)
PARTNER_LIST.each do |partner|
context "with partner #{partner.name}" do
class_exec(&block)
end
end
end
Run Code Online (Sandbox Code Playgroud)
RSpec的DSL通过评估带有变化的块来工作self- 这是it一个describe或一个context块内的方法,但不在它之外.当你yield,所提供的块与原始评价self,这是self在被限定的块的点.这意味着使用您的原始with_each_partner定义,此代码:
describe Thing do
subject { Thing.new(partner) }
with_each_partner do |partner|
it 'does its thing' do
expect(subject.do).to eq 'its thing'
end
end
end
Run Code Online (Sandbox Code Playgroud)
真的被评估如下:
describe Thing do
subject { Thing.new(partner) }
outer_example_group = self
with_each_partner do |partner|
outer_example_group.it 'does its thing' do
expect(subject.do).to eq 'its thing'
end
end
end
Run Code Online (Sandbox Code Playgroud)
...因此,单个示例在外部示例组上定义,而不是在"with partner #{partner.name}"嵌套组上定义.
class_exec 在类/模块的上下文中计算提供的块.在这种情况下,该类是RSpec为您的上下文生成的示例组子类.使用class_exec确保it调用when时,接收器是嵌套context示例组而不是外部示例组,从而创建所需的结果.
| 归档时间: |
|
| 查看次数: |
491 次 |
| 最近记录: |