1

Given two classes that use the template method design pattern:

def Parent
  def all_params
    params.merge(extra_params)
  end

  def params
    {blah: "cool"}
  end

  def extra_params
    {}
  end
end

def Child < Parent
  def extra_params
    {edmund: "coolest"}
  end
end

What is the proper way to test this in Rspec? Should I be creating shared_examples_for "a parent" like this and then testing using it_should_behave_like 'a parent' in both classes?:

shared_examples_for "a parent" do
  describe "#params" do
    expect(subject.params).to eq (...)
  end

  describe "#all_params" do
    expected_params = subject.all_params.merge(subject.extra_params)
    expect(subject.all_params).to eq expected_params
  end
end

describe Parent do
  subject { Parent.new }
  it_should_behave_like 'a parent'

  describe "#extra_params" do
    expect(subject.extra_params).to eq {}
  end
end

describe Child do
  subject { Child.new }
  it_should_behave_like 'a parent'

  describe "#extra_params" do
    expect(subject.extra_params).to eq {edmund: 'coolest'}
  end
end

Or should I be testing that Child is a parent, and only testing the hook methods that it overwrites?

describe Parent do
  subject { Parent.new }
  describe "#params" do
    expect(subject.params).to eq (...)
  end

  describe "#all_params" do
    expected_params = subject.all_params.merge(subject.extra_params)
    expect(subject.all_params).to eq expected_params
  end

  describe "#extra_params" do
    expect(subject.extra_params).to eq {}
  end
end

describe Child do
  subject { Child.new }
  it "is a Parent" do
    expect(subject).to_be kind_of(Parent)
  end

  describe "#extra_params" do
    expect(subject.extra_params).to eq {edmund: 'coolest'}
  end
end
Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
bigpotato
  • 26,262
  • 56
  • 178
  • 334

2 Answers2

0

It's a matter of choice. Personally I create shared examples for the parent class, then for the parent e.g. Animal

include_examples 'Animal'

and for the e.g. Badger < Animal

it_behaves_like 'Animal'

First one includes the example to the current context, while the second one wraps the example in a behaves like Animal context.

Piotr Kruczek
  • 2,384
  • 11
  • 18
0

I prefer the second example. Using it_behaves_like "a parent" in Child is duplicative, and is essentially just testing whether inheritance works in Ruby.

zetetic
  • 47,184
  • 10
  • 111
  • 119