Załóżmy, że masz ActiveRecord :: Observer w jednej z twoich aplikacji Ruby on Rails - w jaki sposób testujesz tego obserwatora za pomocą rSpec?Jak byś przetestował obserwatorów z rSpec w aplikacji Ruby on Rails?
Odpowiedz
Jesteś na prawo śledzić, ale natknąłem się na wiele frustrujących nieoczekiwanych błędów komunikatów podczas korzystania z funkcji rSpec, obserwatorów i obiektów symulowanych. Kiedy testuję swój model, nie chcę mieć do czynienia z zachowaniem obserwatora w moich oczekiwaniach dotyczących wiadomości.
W twoim przykładzie nie ma naprawdę dobrego sposobu na specyfikację "set_status" w modelu bez wiedzy o tym, co obserwator zrobi.
Dlatego chciałbym użyć "No Peeping Toms" plugin. Biorąc kod powyżej i za pomocą wtyczki nr Peeping Toms, chciałbym wg planu model takiego:
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
Można wg planu kod modelu, nie martwiąc się, że jest tam obserwator, który wejdzie i obrzuci twoją wartość. Byłbyś wg planu, który oddzielnie w person_observer_spec jak ten:
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
Jeśli naprawdę bardzo chcesz przetestować sprzężony model i klasę obserwatorem, można to zrobić tak:
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% z tym razem wolałbym przeprowadzić test z wyłączonymi obserwatorami. W ten sposób jest po prostu łatwiej.
Zastrzeżenie: Nigdy rzeczywiście zrobić to na miejscu produkcji, ale wygląda na to rozsądny sposób byłoby użyć makiety obiektów, should_receive
i przyjaciół, i wywoływać metody na obserwatora bezpośrednio
Biorąc pod uwagę następujące Model i obserwator:
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
chciałbym napisać specyfikację takiego (Pobiegłem go i przechodzi)
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
Byliśmy po to podejście i działa cudownie –
no_peeping_toms jest teraz perełka i można znaleźć tutaj: https://github.com/patmaddox/no-peeping-toms
Od Rails 3.1 istnieje metoda wyłączenia dla obserwatorów. –
+1 no_peeping_toms –
Jeśli chcesz przetestować, że obserwator zauważa właściwy model i otrzymał zawiadomienie zgodnie z oczekiwaniami, to jest przykład za pomocą 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
- 1. Uruchamianie phantomjs z aplikacji Ruby on Rails
- 2. Pisanie specyfikacji dla pomocnika z Ruby on Rails i RSpec
- 3. Favicon w Ruby on Rails aplikacji
- 4. Antypatterns z Ruby on Rails
- 5. Ruby on Rails on IIS?
- 6. Jak usunąć układ aplikacji z konkretnej strony Ruby on Rails?
- 7. Docsplit Ruby on Rails
- 8. Ruby vs. Ruby On Rails
- 9. Jak używać ES6 (ES2015) w aplikacji Ruby on Rails?
- 10. Odczytywanie z portu szeregowego w aplikacji Ruby on Rails wisi
- 11. Przełącznik Ruby on Rails
- 12. Jak określić ścieżkę katalogu publicznego w aplikacji Ruby on Rails?
- 13. Ruby on Rails: ssl_required: jak włączyć w całej aplikacji?
- 14. Jak włączyć kompresję w Ruby on Rails?
- 15. Jak łatać małpy w Ruby on Rails?
- 16. Integracja Ruby on Rails z Wordpress
- 17. Zaproszenie do Facebooka z Ruby on Rails
- 18. Ciągłe testowanie integracyjne dla Ruby on Rails z Jenkinsem
- 19. Ruby on Rails - Jak renderować akcję bez układu aplikacji?
- 20. I18n przesyłania w Ruby on Rails
- 21. Wysyłanie do aplikacji Ruby on Rails z Androidem
- 22. Projektowanie stron internetowych z Ruby on Rails
- 23. Problem z połączeniem z Ruby on rails
- 24. Wdrażanie wyszukiwania w aplikacji Ruby on Rails 3?
- 25. Przesyłanie plików HTML5 z Ruby on Rails
- 26. Test RSpec w Ruby on Rails, nie może załadować takiego pliku webmock/rspec
- 27. Ruby on Rails: wybierz formularz
- 28. Ruby on Rails 301 przekierowanie
- 29. Ruby on Rails vs. Django
- 30. Ruby on Rails link_to obrazu
Jeśli chcę przetestować obserwatorów, a wzór, którego używam, to: 'opis PersonOb serwer { wokół (: każdy) {| spec | Person.with_observers (: person_observer) {spec.run}}} 'Pozwala to obserwatorowi na wszystkie testy w bloku opisującym PersonObserver. – roo
Ta odpowiedź jest sformułowana jak odpowiedź, ale nie jest do końca jasne, co. Z pewnością nie odpowiada bezpośrednio na pytanie ... –