2008-08-28 21 views
34

मान लें कि आपके पास रेल अनुप्रयोगों पर आपकी रूबी में से एक में ActiveRecord :: ऑब्जर्वर है - आप इस पर्यवेक्षक को आरएसपीईसी के साथ कैसे परीक्षण करते हैं?रेलवे एप्लिकेशन पर रुबी में आरएसपीसी के साथ पर्यवेक्षकों का परीक्षण कैसे किया जाएगा?

उत्तर

35

आप सही कर रहे हैं ट्रैक करें, लेकिन आरएसपीईसी, पर्यवेक्षकों और नकली वस्तुओं का उपयोग करते समय मैंने कई निराशाजनक संदेश त्रुटियों में भाग लिया है। जब मैं अपने मॉडल का परीक्षण कर रहा हूं, तो मैं अपने संदेश अपेक्षाओं में पर्यवेक्षक व्यवहार को संभालना नहीं चाहता हूं।

आपके उदाहरण में, पर्यवेक्षक के साथ क्या करने जा रहा है, इस बारे में जानकारी के बिना मॉडल पर "set_status" spec का वास्तव में अच्छा तरीका नहीं है।

इसलिए, मैं "No Peeping Toms" plugin. ऊपर अपने कोड और कोई झांक टॉम प्लगइन का उपयोग कर को देखते हुए का उपयोग करने के, मैं इस तरह मॉडल विशिष्ट जानकारी होगी चाहते:

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 

आपको लगता है कि चिंता किए बिना अपने मॉडल कोड विशिष्ट जानकारी कर सकते हैं वहाँ एक पर्यवेक्षक है जो आने और आपके मूल्य को पकड़ने जा रहा है। आप इस तरह person_observer_spec में है कि अलग से विशिष्ट जानकारी चाहते हैं:

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 

आप वास्तव में वास्तव में मिलकर मॉडल और ऑब्जर्वर वर्ग का परीक्षण करना चाहते हैं, तो आप इसे इस तरह कर सकते हैं: के

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% समय, मैं पर्यवेक्षकों के साथ बंद टेस्ट परीक्षण करना चाहता था। यह उस तरह से आसान है।

+0

आप तो काम करता है पर्यवेक्षकों का परीक्षण करना चाहते हैं तो मेरे द्वारा उपयोग किए जाने वाले पैटर्न 'व्यक्ति का वर्णन करें सर्वर { आस-पास (: प्रत्येक) {| spec | Person.with_observers (: person_observer) {spec.run}}} 'यह व्यक्ति ऑब्जेरवर के भीतर सभी परीक्षणों के लिए पर्यवेक्षक को ब्लॉक का वर्णन करता है। – roo

+0

यह उत्तर एक उत्तर की तरह phrased है, लेकिन यह स्पष्ट नहीं है कि क्या। यह निश्चित रूप से सीधे सवाल का जवाब नहीं दे रहा है ... –

15

अस्वीकरण: मैं कभी नहीं वास्तव में इस एक उत्पादन साइट पर किया है, लेकिन ऐसा लगता है कि एक उचित तरीका नकली वस्तुओं, should_receive और दोस्तों के उपयोग करने के लिए होगा, और आह्वान पर्यवेक्षक पर तरीकों सीधे

को देखते हुए निम्नलिखित की तरह मॉडल और पर्यवेक्षक:

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 

मैं इस तरह एक कल्पना लिखते थे (मैं इसे भाग गया, और यह गुजरता है)

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 
+0

हम इस दृष्टिकोण निम्नलिखित किया गया है और यह शानदार –

4

no_peeping_toms अब एक रत्न है और यहां पाया जा सकता: https://github.com/patmaddox/no-peeping-toms

+0

रेल 3 के रूप में।1 पर्यवेक्षकों के लिए एक अक्षम विधि है। –

+0

+1 no_peeping_toms –

2

आप परीक्षण करने के लिए है कि पर्यवेक्षक सही मॉडल का अवलोकन करता है और अधिसूचना के रूप में उम्मीद प्राप्त करता है चाहते हैं, यहाँ आर आर का उपयोग कर एक उदाहरण है।

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