2014-04-12 18 views
8

testen Ich versuche, Logik zu testen, die während der Klassenvererbung ausgeführt wird, aber ein Problem beim Ausführen mehrerer Zusicherungen aufgetreten.wie Ruby Vererbung mit rspec

ich zum ersten Mal versucht, ...

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 

aber dies nicht gelingt, weil die Bar-Klasse bereits geladen worden ist, und daher nicht inherited ein zweites Mal nicht nennen. Wenn die Assertion nicht zuerst ausgeführt wird, schlägt sie fehl.

So dann habe ich versucht, so etwas wie ...

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 

weil @tested nicht von Test bestehen zu testen, wird der Test nicht nur einmal ausgeführt werden.

Wer hat irgendwelche cleveren Möglichkeiten, dies zu erreichen? Dies ist ein konstruiertes Beispiel und i dont tatsächlich Bedarf selbst zu testen, Rubin;)

+0

Testen Sie das Verhalten, nicht Implementierung. Das Testen, ob die Klasse von der Come-Klasse erbt, wäre nur dann sinnvoll, wenn die Methode Meta-Programmierung durchführt (wie Konstruieren von Klassen und Setzen von Ancestoren) –

Antwort

24

Hier ist eine einfache Möglichkeit für Klassenvererbung zu testen mit RSpec:

Gegeben

class A < B; end 

eine viel einfachere Art und Weise Erbe zu testen, mit RSpec:

describe A 
    it { expect(described_class).to be < B } 
end 
+1

Schöne Antwort! Die Erklärung finden Sie hier: http://ruby-doc.org/core-2.3.0/Module.html#method-i-3C –

0

Machen Sie Ihre Klassendefinition für die Prüfung Vererbungslauf während des Tests:

describe 'self.inherited' do 

    before do 
    class Foo 
     def self.inherited klass; end 
    end 
    # For testing other properties of subclasses 
    class Baz < Foo; end 
    end 

    it 'should call self.inherited' do 
    Foo.stub(:inherited) 
    class Bar < Foo; end 
    expect(Foo).to have_received(:inherited).with Bar 
    end 

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

so einfach ... benutzen Sie einfach eine andere Klasse für diesen Einzeltest ... natürlich! Vielen Dank! – brewster

1

Aus irgendeinem Grund habe ich die solution from David Posey nicht verwalten zu arbeiten (ich denke, habe ich etwas falsch. Fühlen Sie sich frei, eine Lösung in den Kommentaren zu bieten). Falls jemand da draußen das gleiche Problem haben, das funktioniert auch:

describe A 
    it { expect(described_class.superclass).to be B } 
end 
1

Für so etwas wie dieses

class Child < Parent; end 

ich in der Regel tun:

it 'should inherit behavior from Parent' do 
    expect(Child.superclass).to eq(Parent) 
end 
Verwandte Themen