Wie würden Sie testen Beobachter mit rSpec in einer Ruby on Rails-Applikation?
-
09-06-2019 - |
Frage
Angenommen, Sie haben ein ActiveRecord::Observer in einem Ihrer Ruby on Rails-Anwendungen - wie tun Sie test dieses Beobachters mit rSpec?
Lösung
Sie sind auf der richtigen Spur, aber ich habe laufen in eine Reihe von frustrierenden unerwartete Nachricht Fehler bei der Verwendung von rSpec, Beobachter und mock-Objekte.Wenn ich die spec Tests mein Modell, ich nicht wollen, zu behandeln Beobachter Verhalten in meiner Nachricht Erwartungen.
In Ihrem Beispiel gibt es keinen wirklich guten Weg spec "set_status" auf das Modell ohne zu wissen, was die Beobachter tun, um es.
Daher benutze ich gerne das "Nein Peeping Toms" - plugin. Ihr code oben und mit der "Nein" Peeping Toms plugin, ich würde spec-Modell wie dieses:
describe Person do
it "should set status correctly" do
@p = Person.new(:status => "foo")
@p.set_status("bar")
@p.save
@p.status.should eql("bar")
end
end
Sie können spec Ihre Modell-code, ohne befürchten zu müssen, dass es Beobachter gibt, die gehen, um in und verpasste Ihr Wert.Sie würden spec, die separat in der person_observer_spec wie diese:
describe PersonObserver do
it "should clobber the status field" do
@p = mock_model(Person, :status => "foo")
@obs = PersonObserver.instance
@p.should_receive(:set_status).with("aha!")
@obs.after_save
end
end
Wenn Sie wirklich, WIRKLICH wollen, um zu testen, das gekoppelte Modell und Beobachter-Klasse, Sie können tun wie diese:
describe Person do
it "should register a status change with the person observer turned on" do
Person.with_observers(:person_observer) do
lambda { @p = Person.new; @p.save }.should change(@p, :status).to("aha!)
end
end
end
99% der Zeit, die ich lieber Skillung-test-mit dem Beobachter ausgeschaltet.Es ist nur einfacher so.
Andere Tipps
Haftungsausschluss:Ich habe eigentlich nie getan, das auf eine Produktionsstätte, aber es sieht aus wie ein sinnvoller Weg wäre die Verwendung von mock-Objekten should_receive
und Freunde, und das aufrufen von Methoden für die Beobachter direkt
Gegeben das folgende Modell und Beobachter:
class Person < ActiveRecord::Base
def set_status( new_status )
# do whatever
end
end
class PersonObserver < ActiveRecord::Observer
def after_save(person)
person.set_status("aha!")
end
end
Ich würde schreiben mit der Spezifikation wie folgt aus (ich habe es, und es geht)
describe PersonObserver do
before :each do
@person = stub_model(Person)
@observer = PersonObserver.instance
end
it "should invoke after_save on the observed object" do
@person.should_receive(:set_status).with("aha!")
@observer.after_save(@person)
end
end
no_peeping_toms ist jetzt ein Juwel und kann hier gefunden werden: https://github.com/patmaddox/no-peeping-toms
Wenn Sie möchten, um zu testen, ob der Beobachter beobachtet das richtige Modell und erhält die Meldung, wie erwartet, hier ein Beispiel mit RR.
your_model.rb:
class YourModel < ActiveRecord::Base
...
end
your_model_observer.rb:
class YourModelObserver < ActiveRecord::Observer
def after_create
...
end
def custom_notification
...
end
end
your_model_observer_spec.rb:
before do
@observer = YourModelObserver.instance
@model = YourModel.new
end
it "acts on the after_create notification"
mock(@observer).after_create(@model)
@model.save!
end
it "acts on the custom notification"
mock(@observer).custom_notification(@model)
@model.send(:notify, :custom_notification)
end