Skip to content

Instantly share code, notes, and snippets.

@jrab89
Last active January 4, 2016 01:29
Show Gist options
  • Save jrab89/8548631 to your computer and use it in GitHub Desktop.
Save jrab89/8548631 to your computer and use it in GitHub Desktop.
Is there a way I can write the second context more concisely by referencing the first?
describe MyClass
let(:instance){MyClass.new}
describe '#myMethod' do
let(:input){ [1] }
context 'with input' do
it 'does stuff' do
instance.should_receive(:foo)
instance.should_receive(:bar)
instance.myMethod(input).should eql true
end
end
context 'with slightly different input' do
before do
input << 2
end
it 'does more stuff' do
instance.should_receive(:foo)
instance.should_receive(:bar)
instance.should_receive(:otherMethod)
instance.myMethod(input).should eql true
end
end
end
end
@cupakromer
Copy link

describe MyClass do

  subject(:instance) { MyClass.new }

  describe "#myMethod" do
    shared_example "a descriptive summary of what foo does" do
      # specs here
    end

    shared_example "a descriptive summary of what bar does" do
      # specs here
    end

    context "with a single input" do
      let(:input) { [1] }

      it_behaves_like "a descriptive summary of what foo does"
      it_behaves_like "a descriptive summary of what bar does"

      it "returns true" do
        expect(instance.myMethod(input)).to be true
      end
    end

    context "with two inputs" do
      let(:input) { [1, 2] }

      it_behaves_like "a descriptive summary of what foo does"
      it_behaves_like "a descriptive summary of what bar does"

      context "a descriptive summary of what otherMethod does" do
        # specs
      end

      it "returns true" do
        expect(instance.myMethod(input)).to be true
      end
    end
  end

end

A few things:

  • RSpec users tend to strive for a single assertion per spec. Here's you seem to be testings between 3 - 4 things each. I'd break those up
  • In this case I am fine with duplicating input across contexts. The reason is they are not meant to be the exact same input. They represent contextually different values; thus I do not view them as extractable beyond each context's specs.
  • In general, stubbing / expecting methods to be called on the object under test is viewed as a bad practice. Instead, check the expectations that those objects do. If it is a few things, extract that out into shared examples
  • Repeating some tests between contexts is fine. DRY is more about having one authoritative place for the declaration of something; not necessarily that you don't ever repeat code. The repetition of code is fine in some cases and is usually called coincidental duplication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment