Repeating groups of RSpec examples with different arguments

I am trying to keep my specifications clean and dry, but I have some tests for the API that are identical, except what version of the API is being tested. I could repeat the specifications simply using something like this:

%w( v1 v2 ).each do |version|
  describe "Query #{version} API" do
    it "responds with JSON"
      # make the call using the version 
    end
  end
end

But I would like something to be a little cleaner, and so I wrote this method:

module RepetitivelyDescribe
  def repetitively_describe(*args, &example_group_block)
    options = args.extract_options!
    options.delete(:for).each do |item|
      item_args = args.collect(&:dup) + [options.dup]
      item_args[0] << " [#{item}]"

      describe(*item_args) do
        example_group_block.call item
      end
    end
  end
end

RSpec::Core::ExampleGroup.extend RepetitivelyDescribe

And then my test might look something like this:

repetitively_describe "Query API", :for => %( v1 v2 ) do |version|
  it "responds with JSON"
    # make the call using the version 
  end
end

I understand that this is a bit of pedantry, but this is one level less indentation, and if I am going to make this call a lot, I would like it to be cleaner.

, , , . describe repetitively_describe RSpec ( ), , . , ( describe repetitively_describe).

gist. , ?

+5
1

(, , ), , describe/context, rspec , ( RSpec::Core::ExampleGroup), module_eval .

describe "foo" do
  puts "#{self}; #{self.superclass}"
  describe "behaviour 1" do
    puts "#{self}; #{self.superclass}"
    context "with x" do
      puts "#{self}; #{self.superclass}"
    end
  end
end

#<Class:0x007fb772bfbc70>; RSpec::Core::ExampleGroup
#<Class:0x007fb772bfb180>; #<Class:0x007fb772bfbc70>
#<Class:0x007fb772bfa5f0>; #<Class:0x007fb772bfb180>

it rspec Example self ( ). rspec , , .

repetitively_describe describe, , example_group_block.call item, . proc , , , , self, , it , , repetitively_describe ( , , ). , repetitively_describe.

, , , example_group_block, self.

module RepetitivelyDescribe
  def repetitively_describe(*args, &example_group_block)
    options = args.extract_options!
    options.delete(:for).each do |item|
      item_args = args.collect(&:dup) + [options.dup]
      item_args[0] << " [#{item}]"

      describe(*item_args) do
        class_exec(item, &example_group_block)
      end
    end
  end
end

describe('foo') do
  repetitively_describe "Query API", :for => %w( v1 v2 ) do |version|
    it "responds with JSON"
  end
end.descendant_filtered_examples.collect(&:full_description)

["foo Query API [v1] responds with JSON", "foo Query API [v2] responds with JSON"] ["foo responds with JSON", "foo responds with JSON"] .

+5
source

All Articles