2012-06-01 28 views
32

क्या आरएसपीईसी का उपयोग करते समय किसी भी स्टबिंग और मॉकिंग को हटाने का कोई तरीका है?आरएसपीईसी में, क्या "unstub" के बराबर एक विधि है लेकिन "should_receive" के लिए?

उदाहरण:

RestClient.should_receive(:delete).with("http://www.example.com") 
... 
... 

# this will remove the mocking of "should_receive" and 
# restore the proper "delete" method on "RestClient". 
RestClient.mocking_reset 

(mocking_reset कार्यक्षमता की आवश्यकता के लिए मेरे फर्जी नाम है)।

मुझे पता है कि "unstub" विधि है जो "stubs" को रीसेट करता है लेकिन "should_receive" नहीं।

तो, क्या "unstub" के बराबर कोई विधि है लेकिन "should_receive" के लिए?

Panayotis

+0

यह हास्यास्पद है कि आप 6 से कम वर्णों का संपादन नहीं कर सकते! वहां आपका विधि नाम 'mocking_resest' कहता है और इसे' mocking_reset' कहना चाहिए। –

+0

एक संपादन संदेश जोड़ें और आपका संपादन 6 वर्णों से अधिक हो जाएगा :) – Galen

उत्तर

29

फिलहाल (rspec-mocks 2.10.1) वहाँ नहीं unstub लेकिन should_receive के लिए एक विधि के बराबर है। आप rspec_reset का उपयोग करके सभी स्टब्स और मैक्स को रीसेट कर सकते हैं, और आप एक विशेष उम्मीद को हटाने के लिए गंदे हैक भी लिख सकते हैं (जिसे मैं अनुशंसा नहीं करता)।

निम्नलिखित एक वस्तु पर सभी स्टब्स और अपेक्षाओं को दूर करने का एक उदाहरण है:

इस विधि जिसका अर्थ है कि आप इसे और अधिक से अधिक का उपयोग करने से बचना चाहिए @private रूप rspec स्रोत कोड, में टिप्पणी की जाती है
describe "resetting stubs and expectations with rspec_reset" do 
    before do 
    @person = mock('person') 
    @person.should_receive(:poke) 
    end 

    it "should not fail when we reset all stubs and expectations" do 
    @person.rspec_reset 
    end 
end 

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

थोड़ा अधिक rspec-mocks कोड के माध्यम से खुदाई के बाद, आप निश्चित रूप से वास्तव में कुछ बुरा करते हैं और अपने आप को एक विशिष्ट उम्मीद को फाड़ कर सकते हैं:

# Works in rspec 2.10.1 
describe "removing an expectation with an ugly hack" do 
    before do 
    @person = mock('person') 
    @person.should_receive(:poke) 
    end 

    it "should not fail after we hack rspec by violating every law of good programming, ever" do 
    @person.instance_variable_get(:@mock_proxy).instance_variable_get(:@method_double)[:poke].clear 
    end 
end 

यह वास्तव में बुरा है, क्योंकि यह एक कैप्सूल का उल्लंघन करता है आरएसपीसी परीक्षण पैकेज और आपको यह नहीं करना चाहिए। इसके बजाए, यदि आपके पास वास्तव में किसी विशेष अपेक्षा को हटाने के लिए एक अनिवार्य कारण था, तो सही काम करने के लिए rspec-mocks में एक सार्वजनिक विधि अपस्ट्रीम जोड़ना होगा जो unstub पर समांतर विधि जोड़ता है लेकिन विशिष्ट अपेक्षाओं को हटाने के लिए। यह शायद यहाँ स्थित होगा (stub और unstub की परिभाषा के रूप में अच्छी तरह से में इस फाइल पर ध्यान दें):

https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/methods.rb

बाहर जा रहा है और किसी भी सुझाव को उपयोग करने से पहले ऊपर उम्मीद दूर करने के लिए आप अगर विचार कर सकते हैं आपकी चश्मा वास्तव में ऐसा करने की ज़रूरत है या अगर उन्हें दोबारा इस्तेमाल किया जाना चाहिए। should_receive का उपयोग करना आपके कोड के बारे में एक दावा है, और आमतौर पर आपको उदाहरण बनाने की कोशिश करनी चाहिए (यानी it ब्लॉक) जो केवल एक चीज का दावा करती है। मैं बहुत उत्सुक हूं कि आपको rspec_reset की आवश्यकता क्यों है जब तक कि आप वैश्विक सेटअप में बहुत अधिक करने की कोशिश नहीं कर रहे हैं (उदाहरण के लिए before :each या इससे पहले: सभी ब्लॉक), या यदि आपके उदाहरण बहुत अधिक करने की कोशिश कर रहे हैं (यानी। एक उदाहरण में कई दावे)।

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

मुझे आशा है कि इससे मदद मिलेगी और कृपया मुझे बताएं कि अगर आपको लगता है कि unstub पर समकक्ष विधि जोड़ने के लिए एक वैध मामला है, लेकिन संदेश अपेक्षाओं के लिए (यानी, should_receive का उपयोग करने के बाद)। अगर मुझे आश्वस्त है कि यह करना ठीक है तो मैं इस विधि को जोड़ने और इसे अपस्ट्रीम जोड़ने का प्रस्ताव देने पर विचार करूंगा। शायद इसे unset_expectation कहा जाएगा? कृपया अपने आप पर rspec-mocks के लिए पुल अनुरोध को एक साथ रखने के लिए उपरोक्त कोड और आंतरिक संरचनाओं में मार्गदर्शन का उपयोग करने के लिए स्वतंत्र महसूस करें, और हम देखेंगे कि यह unstub के बराबर मॉकिंग बनाने के लिए स्वीकार किया जाता है या नहीं।

+1

आपके उत्तर के लिए बहुत बहुत धन्यवाद। कारण मैं चाहता था कि यह कार्यक्षमता इसलिए थी क्योंकि मेरे पास "clean_test_data" विधि "प्रत्येक के बाद" निष्पादित की गई थी। यह वास्तविक तरीकों का उपयोग करने के लिए आवश्यक है। एसओएफ पर अपना प्रश्न पोस्ट करने के बाद, मुझे एहसास हुआ है कि मैं अभी भी "clean_test_data" का उपयोग कर सकता हूं लेकिन "पहले: प्रत्येक" पर और यह मेरी समस्या का समाधान था। इस तरह, मुझे अंततः किसी भी अनावश्यक या अनमॉक की आवश्यकता नहीं थी। इस बीच, चूंकि मुझे अतीत में "unstub" का उपयोग करने के अच्छे कारण मिलते हैं, तो मुझे नहीं लगता कि पूर्णता के कारणों के बराबर "unset_expectation" क्यों नहीं है और फिर नकली उपयोगकर्ता निर्णय लेते हैं। –

6

आरएसपीसी> = 2.14 के लिए, स्वीकृत उत्तर अब काम नहीं करेगा। मैं इस सूत्र (लिंक रोट के खिलाफ की रक्षा करने के लिए नीचे दिए गए reproduced) पर बर्नहार्ड कोहलर के जवाब का उल्लेख: undefined method `rspec_reset' with rspec version 2.14

रीसेट करने की विधि RSpec 2.14 में मौजूद नहीं है। इसके बजाए, यह एक सहायक rspec-mocks प्रोजेक्ट के लिए spec_helper.rb फ़ाइल के अंदर परिभाषित विधि है।

module VerifyAndResetHelpers 
    def verify(object) 
    RSpec::Mocks.proxy_for(object).verify 
    end 

    def reset(object) 
    RSpec::Mocks.proxy_for(object).reset 
    end 
end 

आप देख सकते हैं कि इस विधि प्रतिनिधियों बजाय प्रश्न में वस्तु के वर्ग परिभाषा के लिए उस पर टैकिंग के अंतर्निहित प्रॉक्सी पर रीसेट कार्रवाई।

31

आप से कुछ पिछले मजाक के ऊपर लिख सकते हैं:

expect(RestClient).to receive(:delete).and_call_original 

या उम्मीद के किसी भी प्रकार, बस एक साधारण ठूंठ नहीं था अगर यह होता है:

allow(RestClient).to receive(:delete).and_call_original 

वहाँ याद भी मौजूद है expect_any_instance_of और allow_any_instance_of