Karol Selak
Karol Selak

Reputation: 4804

How to DRY an RSpec code that tests similar methods of the same class?

I have such a code:

RSpec.describe CypherFileExecution do
  describe "self.drop_data_and_execute" do
    # (...)
    it "drops old data" do
      # (...)
    end
    it "executes cypher file" do
      described_class.drop_data_and_execute('spec/seeds/neo4j_object_spec.cypher')
      expect([
        does_object_exist_in_db?("relationship-class"),
        does_object_exist_in_db?("class-instance-class"),        
      ]).to eql [true, true]
    end
  end
  describe "self.execute" do
    it "executes cypher file" do
      described_class.execute('spec/seeds/neo4j_object_spec.cypher')
      expect([
        does_object_exist_in_db?("relationship-class"),
        does_object_exist_in_db?("class-instance-class"),        
      ]).to eql [true, true]
    end
  end
end

As we can see, the "executes cypher file" blocks are the same for both methods (in fact, one of them calls another one). What can I do to make this code DRY? If I'm not mistaken, shared examples and contexts work at the class level, but I have the method level here. What should I do?

Upvotes: 1

Views: 598

Answers (1)

Matthieu Libeer
Matthieu Libeer

Reputation: 2365

This is a use case for shared examples, which we can use in conjonction with subject, leveraging RSpec's lazy evaluation.

RSpec.describe CypherFileExecution do
  shared_examples 'executes cypher file' do
    it "executes cypher file" do
      subject
      expect(does_object_exist_in_db?("relationship-class")).to be(true)
      expect(does_object_exist_in_db?("class-instance-class")).to be(true)
    end
  end

  describe "self.drop_data_and_execute" do
    subject { described_class.drop_data_and_execute('spec/seeds/neo4j_object_spec.cypher') }
    include_examples 'executes cypher file'

    # (...)
    it "drops old data" do
      # (...)
    end
  end

  describe "self.execute" do
    subject { described_class.execute('spec/seeds/neo4j_object_spec.cypher') }
    include_examples 'executes cypher file'
  end
end

Upvotes: 3

Related Questions