2011-05-04 20 views
12

में आरएसपीईसी के साथ पहले से पहले सही तरीके से काम करता है यह जांचने के लिए कि मेरे पास मेरे एप्लिकेशन नियंत्रक में check_user_access_control पहले_फिल्टर है जो लॉग इन उपयोगकर्ता की भूमिकाओं और अनुमतियों को उसके माध्यम से जाने से पहले जांचता है। मैं इस पर कुछ परीक्षण लिखने की कोशिश कर रहा हूं और मुझे ऐसा करने का अच्छा तरीका नहीं मिल रहा है।रेलवे

सरल सूचकांक कार्यों के लिए मैं बस कार्य करें:

it "allows access to mod" do 
    login_as(Factory(:mod)) # this is a spec helper 
    get :index 
    response.code.should == "200" 
end 

और यह सिर्फ ठीक काम करता है। संपादन/शो/निर्माण और अन्य क्रियाओं के लिए जिन्हें कुछ पैरा की आवश्यकता होती है, डेटाबेस के साथ बातचीत और चलाने के बाद संभावित रीडायरेक्ट के लिए, इसे स्टब किए जाने के लिए बहुत सी अन्य चीजों की आवश्यकता होती है।

क्या यह जांचने का कोई तरीका है कि पहले_फिल्टर के बाद कोई विशिष्ट क्रिया कहा गया है या नहीं? मैं controller.should_receive(:action_name) (जो काम नहीं करता) की तरह कुछ ढूंढ रहा हूं response.code.should == "200" लाइन को प्रतिस्थापित करने के लिए।

संस्करण: 3.0.4 और rspec 2.5

मैं एक और दृष्टिकोण की कोशिश की रेल। हमारे पास redirect_to_login नामक एप्लिकेशन कंट्रोलर में एक विधि है जिसे मैं अब controller.should_receive(:redirect_to_login) के साथ जांच रहा हूं और काम करता हूं।

हालांकि उपयोगकर्ता को अनुमति दी जाती है या नहीं, तो यह सही ढंग से पता लगाती है, यह विधि को रोकती है, जिसका अर्थ है कि नियंत्रक कार्रवाई चलती है या नहीं, उपयोगकर्ता को अनुमति है या नहीं। इसके अलावा कार्रवाई पैरा और डेटाबेस पर निर्भर करती है और हम इसे नहीं चाहते हैं।

यदि अब मैं controller.stub!(:action_name) के साथ क्रिया विधि को दबाता हूं, तो कार्रवाई नहीं चलती है लेकिन आरएसपीईसी अभी भी टेम्पलेट की तलाश में है। खैर, कुछ कार्यों में टेम्पलेट नहीं होते हैं, वे सिर्फ redirect_to :action => :somewhere_else या render :text => "foobar" के साथ समाप्त होते हैं, इस बिंदु पर हमें परवाह नहीं है।

क्रम में, मुझे अब क्या चाहिए, आरएसपीसी टेम्पलेट के अस्तित्व के बारे में चिंता करने का तरीका ढूंढना है।

उत्तर

7

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

उदा।

controller.should_receive(:redirect_to_log) { redirect_to login_url } 

या

controller.should_receive(:redirect_to_log) { raise StandardError.new('login error') } 
expect { get :index }.to raise_error 

अधिक जानकारी के लिए भयानक rspec documentation की जाँच करें।

उम्मीद है कि यह मदद करता है।

+0

पर पोस्ट पहले खंड नहीं मालूम था काम करने के लिए, लेकिन दूसरा एक (एक है कि एक त्रुटि को जन्म देती है) एक आकर्षण की तरह काम किया! अब, इसके विपरीत करने के लिए एक रास्ता खोजने के लिए: उदाहरण में, जब हमारे पास 'controller.should_not_receive (: redirect_to_log)' है, तो कार्रवाई विधि को चलने से रोकें। – Kostas

+0

आम तौर पर मैं निश्चित रूप से उस विधि का परीक्षण करता हूं जिसका उपयोग आप 'पहले_फिल्टर' स्टैंडअलोन के रूप में करते हैं: उपयोगकर्ता को दिया गया है, क्या यह सही निर्णय लेता है कि पहुंच की अनुमति है या नहीं। अपने नियंत्रक पर आप केवल परीक्षण कर सकते हैं: यदि किसी उपयोगकर्ता को एक्सेस की अनुमति नहीं दी जानी चाहिए, तो 'redirect_to_log' को कॉल किया जाना चाहिए (जो मैंने ऊपर दिखाया है)। यदि किसी उपयोगकर्ता के पास पहुंच है, तो 'redirect_to_log' को नहीं कहा जाना चाहिए, और 'response.status.should == 200' (उस स्थिति में मुझे लगता है कि आपको विचारों को ढूंढने में परेशानी नहीं होगी, है ना?)। तो बस परीक्षण करें कि यह सफलतापूर्वक काम करता है। – nathanvda

+0

मैंने इस दृष्टिकोण की कोशिश की लेकिन समस्या यह है कि कुछ क्रियाएं (जैसे बनाना) 200 के साथ समाप्त नहीं होती है लेकिन 302 (दिखाने के लिए रीडायरेक्ट) के साथ समाप्त होती है। इसके अलावा उनमें से कुछ को ट्राम की एक टन और डीबी तक पहुंच की आवश्यकता होती है (यहां तक ​​कि उनमें से कुछ के लिए फाइल सिस्टम एक्सेस) कि मैं बाई-पास करना चाहता हूं क्योंकि आप केवल इतना ही रोक सकते हैं। ** एक्शन विधि को स्वयं चलाना ही मुझे मार रहा है क्योंकि यह इन प्राधिकरण परीक्षणों का उद्देश्य नहीं है। ** – Kostas

0

@nathanvda's answer का विस्तार करने के लिए:

जब छोटा करते, आप अभी भी एक डमी कार्यान्वयन दे सकता है। उस कार्यान्वयन के अंदर [...] वैसे भी एक रीडायरेक्ट करें।

आप ब्लॉक में controller निर्दिष्ट करना होगा:

expect(controller).to receive(:redirect_to_log) { controller.redirect_to login_url } 

RSpec एक मिलान भी redirect_to कि पूर्वता लेता है जब विधि को देख कहा जाता है है।इसे सीधे नियंत्रक पर कॉल करना उस के आसपास काम करता है।

0

nathanvda करने के लिए धन्यवाद के साथ अंतिम समाधान,:

it "allows access to moderator" do 
    login_as(Factory(:mod)) 
    controller.stub!(action) { raise "HELL" } 

    controller.should_not_receive(:redirect_to_login) 
    expect { get action }.to raise_error(/HELL/) 
end 

it "denies access to user" do 
    login_as(Factory(:user)) 

    controller.should_receive(:redirect_to_login) { raise "HELL" } 
    expect { get :index }.to raise_error(/HELL/) 
end 

https://gist.github.com/957565

संबंधित मुद्दे