2013-03-06 3 views
36

यह आरएसपीईसी दस्तावेज़ में कहा गया है कि मुझे टेस्ट डबल बनाने के लिए double विधि का उपयोग करना चाहिए। लेकिन मैं देख सकता हूं कि यह पूरी तरह से ठीक काम करता है भले ही मैं double का उपयोग न करें। double का उपयोग न करने में कुछ गड़बड़ है? अगर मैं डबल का उपयोग नहीं कर रहा हूं तो MyClassstub और अन्य आरएसपीईसी विधियों को कैसे प्राप्त करता है? क्या वे rspec में चलते समय सभी ऑब्जेक्ट्स के लिए उपलब्ध हैं?rspec में डबल विधि क्या है?

require 'spec_helper' 

class MyClass 

    def self.run 
     new.execute 
    end 

    def execute 
     'foo' 
    end 

end 

describe MyClass do 

    it 'should stub instance method' do 
     obj = MyClass.new 
     obj.stub(:execute).and_return('bar') 
     obj.execute.should == 'bar' 
    end 

    it 'should stub class method' do 
     MyClass.stub(:run).and_return('baz') 
     MyClass.run.should == 'baz' 
    end 

end 

उत्तर

40

संपादित करें: मैं सिर्फ अपने प्रश्न पुन: पढ़ने और महसूस किया कि मैं काफी यह जवाब नहीं दिया। मेरा मूल उत्तर छोड़कर क्योंकि यह संबंधित है, लेकिन यहां आपका विशिष्ट उत्तर है:

कारण आपको डबल की आवश्यकता नहीं है क्योंकि आप उदाहरण विधियों के बजाय कक्षा विधियों को दबा रहे हैं। double कक्षा के उदाहरणों से निपटने के लिए केवल उपयोगी है, न कि वर्ग स्वयं।

पुराना जवाब है कि डबल कुछ और बताते हैं:

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

इसका एक अधिक सटीक उदाहरण है: मान लीजिए कि आप MyClass का परीक्षण कर रहे हैं, लेकिन आदेश MyClass का दृष्टांत के लिए, आपको एक FooLogger में पारित करने के लिए की जरूरत है:

mylogger = FooLogger.new 
myclass = MyClass.new logger: mylogger 

तो FooLogger.new किसी syslog सॉकेट खोलता है और यह सही स्पैमिंग शुरू होता है दूर, हर बार जब आप अपना परीक्षण चलाते हैं, तो आप लॉगिंग करेंगे। आप इस परीक्षण के दौरान आपके लॉग स्पैम नहीं करना चाहते हैं, तो आप के बजाय FooLogger के लिए एक डबल बना सकते हैं और उस पर एक विधि बाहर ठूंठ कर सकते हैं:

mylogger = double(FooLogger) 
mylogger.stub(:log) 
myclass = MyClass.new logger: mylogger 

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

मेरे अनुभव में, डबल का उपयोग करने की आवश्यकता एक कोड गंध है, लेकिन हमें अक्सर उन वर्गों का उपयोग करना पड़ता है जिन्हें हम आसानी से नहीं बदल सकते हैं (उदाहरण के लिए एक मणि से), इसलिए यह एक उपकरण है जिसे आपको समय-समय पर आवश्यकता हो सकती है ।

+0

वास्तव में आप मेरी उदाहरण में, पहले कल्पना स्टब्स ** उदाहरण विधि ** और दूसरा एक स्टब्स ** वर्ग विधि ** देखो जब। ऐसा लगता है कि दोनों काम ठीक है, पहले इस्तेमाल नहीं किए गए 'डबल' के साथ। यही कारण है कि मुझे आश्चर्य है कि एक अतिरिक्त जादू 'डबल' मुझे क्या देता है। – grafthez

+0

इस उदाहरण पर एक नज़र डालें मैंने https://gist.github.com/anonymous/5101448 बनाया है। अगर मैं 'शेड्यूलर जॉब' का परीक्षण करना चाहता हूं तो मुझे 'RequestSchedule'' को दबाए रखना होगा और 'RequestToQueuePusher' को ठीक करना होगा? मुझे भी परेशान करता है कि 'शेड्यूलर जोब' दो शेष वर्गों के साथ कसकर मिलकर है। जैसे ही मैं जावा दुनिया से आया हूं, मैं आम तौर पर उन्हें निर्भरता के रूप में निकाल दूंगा क्योंकि नकली वस्तुओं का कोई आसान तरीका नहीं है जो कठोर कोडित तरीके से बनाए जाते हैं। रुबी में ऐसा लगता है कि यह कोई मुद्दा नहीं है। मैं अपने 'शेड्यूलर जोब' जैसी बहुत सारी वस्तु देखता हूं। मुझे पता है कि उन्हें आसानी से नकली करने का एक तरीका है, लेकिन मेरे लिए यह कुछ सोलिड सिद्धांतों का उल्लंघन करता है – grafthez

+0

यह रूबी दुनिया में भी खराब डिजाइन है। परीक्षण को आसान बनाने के लिए RequestSchedule निर्भरता को इंजेक्ट करने का एक तरीका होना चाहिए। आप ऐसा कुछ कर सकते हैं: 'fakeschedule = double (RequestSchedule); RequestSchedule.stub (नई) .and_return (fakeschedule); '। यह निश्चित रूप से refactored किया जाना चाहिए। –

0

आरएसपीसी मोक्स 3.0 के साथ युगल का व्यवहार बदल गया है। अब आप verify doubles कर सकते हैं, जिसका अर्थ है "आरएसपीसी जांच करेगा कि स्टब किए जाने के तरीके वास्तव में अंतर्निहित ऑब्जेक्ट पर उपलब्ध हैं यदि यह उपलब्ध है", लेकिन "अंतर्निहित वस्तु या वर्ग परिभाषित नहीं किया गया है तो कोई जांच नहीं होगी"।

युगल अनुरोधों को सत्यापित करना आपको डबल प्रकार (उदाहरण, कक्षा, वस्तु, गतिशील वर्ग, आंशिक) के बारे में विशिष्ट होना चाहिए।यहाँ एक उदाहरण डबल के लिए RSpec Relish से एक उदाहरण है:

RSpec.describe User, '#suspend!' do 
    it 'notifies the console' do 
    notifier = instance_double("ConsoleNotifier") 

    expect(notifier).to receive(:notify).with("suspended as") 

    user = User.new(notifier) 
    user.suspend! 
    end 
end