【问题标题】:Create RSpec context inside a function在函数内创建 RSpec 上下文
【发布时间】:2014-10-24 07:42:22
【问题描述】:

为了避免在我的 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 正确处理在我的函数中创建的上下文?

【问题讨论】:

    标签: ruby-on-rails ruby rspec


    【解决方案1】:

    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 的块来工作——这就是 itdescribecontext 块内的方法,但不在它之外。当您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
    

    真的是这样评价的:

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

    【讨论】:

    • dang,我认为这几乎是我在 SO 上得到的最佳答案。 +1
    • 嘿。嗯...我相信这位先生对rspec 有点熟悉。
    • 您好!我对你的回答有疑问。当您执行 class_exec(&block) 时,您如何将伙伴传递到该块中,以便在该块中可以访问它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多