2016-04-16 24 views
1

Ich beginne gerade mit Ruby und Rspec, also wenn ich nicht sehr spezifisch bin entschuldige ich mich für meine schlechte Syntax im Voraus.Aufruf einer Methode aus einer anderen Klasse ruby ​​

Ich habe zwei Klassen, Flughafen und Wetter, die sollten kommunizieren, damit ich die stormy? Methode in Wetter vom Flughafen anrufen kann. Ich möchte verhindern, dass Flugzeuge abheben, wenn das Wetter schlecht ist. Ich habe definiert eine bad_weather Methode, aber es funktioniert nicht Hier ist mein Code:

Mein Test in Rspec

describe Airport do 
    it ' does not allow planes to take off with stormy weather' do 
    subject.take_off double(:plane) 
    expect {(weather).to be_stormy?}.to raise_error "Flight cancelled due to bad weather" 
    end 
end 

Die Klasse ich die Methode nehmen wollen von

class Weather 

    def stormy? 
    roll >= 6 
    end 

private 

    def roll 
    rand(10) 
    end 
end 

Und die Klasse möchte ich die Methode in

class Airport 

    DEFAULT_CAPACITY = 10 

    def initialize 
    @planes = [] 
    @capacity = DEFAULT_CAPACITY 
    end 


    def take_off(plane) 
    fail "Flight cancelled due to bad weather" if bad_weather? 
    @planes.pop 
    end 

    def bad_weather? 
    weather = Weather.new 
    weather.stormy? 
    end 
end 
anrufen

Ich kenne meinen Rspec Test miserabel, jede Hilfe wäre willkommen.

+0

Was macht es stattdessen? – 13aal

Antwort

3

Wenn Sie Situationen haben, in denen sich das zu testende Objekt auf andere Objekte verlässt, möchten Sie die Kontrolle über diese Objekte haben. In Ihrem Szenario möchten Sie die weather steuern, die Ihr airport kennt.

Um dies zu tun, müssen Sie es zwingen, dass, wenn Sie stormy? fragen, es true zurückgibt. Auf diese Weise stellen Sie sicher, dass Sie Ihre Einheit Airport testen und alle Abhängigkeiten von anderen Objekten unter Kontrolle sind.

Hier ist, wie ich dies tun würde:

class Airport 
    DEFAULT_CAPACITY = 10 

    def initialize 
    @planes = [] 
    @capacity = DEFAULT_CAPACITY 
    end 

    def take_off(plane) 
    fail "Flight cancelled due to bad weather" if bad_weather? 
    @planes.pop 
    end 

    def bad_weather? 
    weather.stormy? 
    end 

    def weather 
    @weather ||= Weather.new 
    end 
end 

Und dann in Ihrem Test, werden Sie zu kontrollieren, was weather Ihr Flughafen hat dies tun:

it 'does not allow planes to take off with stormy weather' do 
    my_airport = Airport.new 
    stormy_weather = Weather.new 
    allow(stormy_weather).to receive(:is_stormy?) { true } 
    allow(my_airport).to receive(:weather) { stormy_weather } 

    expect(my_airport.take_off("Boeing")).to raise_error "Flight cancelled due to bad weather" 
end 

@SteveTurczyn Antwort auch gültig. Ich persönlich mag es nicht, weil Sie nicht nur das Wetter an Ihrem Flughafen stürmisch machen, sondern auch jede andere Instanz.

0

Die Technik zum Testen ist, um #stormy? zu erzwingen, und dann zu testen, dass ein Take_off-Methodenaufruf den Fehler auslöst.

it 'does not allow planes to take off with stormy weather' do 
    allow_any_instance_of(Weather).to receive(:stormy?).and_return(true) 
    my_airport = Airport.new 
    expect(my_airport.take_off("Boeing")).to raise_error "Flight cancelled due to bad weather" 
end 

Übrigens Sie wollen auch die Umkehrung der Bedingung testen, so wäre ein weiterer Test nützlich sein.

Verwandte Themen