gpt4 book ai didi

ruby-on-rails - 在函数内创建 RSpec 上下文

转载 作者:数据小太阳 更新时间:2023-10-29 06:58:46 25 4
gpt4 key购买 nike

为了避免在我的 Rspec 测试中重复自己很多,我想写一个这样的函数

def with_each_partner(&block)
PARTNER_LIST.each do |partner|
context "with partner #{partner.name}" { yield partner }
end
end

我有这样一个功能,它的工作原理是所有测试都以提供的合作伙伴的正确值运行,但它们不会在输出期间打印为“与合作伙伴 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

我最终得到这样的输出:

Thing
does its thing

而不是像这样的所需输出:

Thing
with partner X
does its thing
with partner Y
does its thing

如何让 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

说明

RSpec 的 DSL 通过评估具有更改的 self 的 block 来工作——这就是 itdescribe 中的方法的方式>context block ,但不在它之外。当您 yield 时,所提供的 block 将使用原始 self 进行评估,该 block 在定义 block 时是 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

真的是这样被评价的:

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

...因此,各个示例是在外部示例组中定义的,而不是在 "with partner #{partner.name}" 嵌套组中定义的。

class_exec evaluates the provided block in the context of the class/module .在这种情况下,该类是 RSpec 为您的上下文生成的示例组子类。使用 class_exec 确保调用 it 时,接收者是您嵌套的 context 示例组而不是外部示例组,从而创建您想要的结果.

关于ruby-on-rails - 在函数内创建 RSpec 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26538952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com