Creating an RSpec Context Inside a Function

In order not to repeat myself in my Rspec tests, I would like to write a function like

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

I have such a function, and it works in the sense that all tests run with the correct value for the supplied partner, but they are not printed during output as part of the "partner X" context: instead, if I have such a test:

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

As a result, I get the output as follows:

Thing
  does its thing

Instead of the desired output, which looks like this:

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

How can I get RSpec to work correctly with the context created in my function?

+4
source share
1 answer

TL DR: do the following:

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

Explanation

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

:

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 /. , RSpec . class_exec , it context, , .

+6

All Articles