Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to test ruby inheritance with rspec

Tags:

ruby

rspec

I am trying to test logic that runs during class inheritance, but have run into an issue when running multiple assertions.

i first tried...

describe 'self.inherited' do
  before do
    class Foo
      def self.inherited klass; end
    end

    Foo.stub(:inherited)

    class Bar < Foo; end
  end

  it 'should call self.inherited' do
    # this fails if it doesn't run first
    expect(Foo).to have_received(:inherited).with Bar
  end

  it 'should do something else' do
    expect(true).to eq true
  end
end

but this fails because the Bar class has already been loaded, and therefore does not call inherited a 2nd time. If the assertion doesn't run first... it fails.

So then i tried something like...

describe 'self.inherited once' do
  before do
    class Foo
      def self.inherited klass; end
    end

    Foo.stub(:inherited)

    class Bar < Foo; end
  end

  it 'should call self.inherited' do
    @tested ||= false
    unless @tested
      expect(Foo).to have_receive(:inherited).with Bar
      @tested = true
    end
  end

  it 'should do something else' do
    expect(true).to eq true
  end
end

because @tested doesn't persist from test to test, the test doesn't just run once.

anyone have any clever ways to accomplish this? This is a contrived example and i dont actually need to test ruby itself ;)

like image 275
brewster Avatar asked Apr 12 '14 06:04

brewster


2 Answers

Here's an easy way to test for class inheritance with RSpec:

Given

class A < B; end

a much simpler way to test inheritance with RSpec would be:

describe A do
  it { expect(described_class).to be < B }
end
like image 70
David Posey Avatar answered Sep 19 '22 19:09

David Posey


For something like this

class Child < Parent; end

I usually do:

it 'should inherit behavior from Parent' do
  expect(Child.superclass).to eq(Parent)
end
like image 43
dimitry_n Avatar answered Sep 21 '22 19:09

dimitry_n