2009-07-22 8 views
32

क्या एक rspec परिदृश्य में Kernel.sleep stub करने का कोई तरीका है?आरएसपीसी: कर्नेल :: सोना stubbing?

+0

आप से परे कुछ के लिए देख रहे कर्नेल :: स्टब्स (: नींद) –

+0

मुझे लगता है कि वह इसे काम करना चाहता है और सो नहीं सकता है, शायद उसका परीक्षण धीमा कर रहा है ... – Rich

उत्तर

43

आपको बुला रहे हैं, तो नींद है एक वस्तु के संदर्भ में, आप वस्तु पर यह ठूंठ चाहिए, ताकि जैसे:

class Foo 
    def self.some_method 
    sleep 5 
    end 
end 

it "should call sleep" do 
    Foo.stub!(:sleep) 
    Foo.should_receive(:sleep).with(5) 
    Foo.some_method 
end 

कुंजी है, पर नींद ठूंठ जो भी "स्वयं" संदर्भ में है जहां नींद कहा जाता है।

+1

मेरे लिए बहुत अच्छा काम किया, चीयर्स! – opsb

+0

परीक्षण के तहत वस्तु को दबाकर एक अच्छा विचार नहीं है। उदाहरण के लिए, देखें: http://robots.thoughtbot.com/don-t-stub-the-system-under-test – georgebrock

+1

@georgebrock अप्रासंगिक कारण के लिए, है ना? मेरा मानना ​​है कि [यह] (http://stackoverflow.com/a/27749263/52499) वह तरीका है जो सर्वोत्तम इरादे को व्यक्त करता है। और नए वाक्यविन्यास का उपयोग करना चाहिए। 'allow_any_instance_of (ऑब्जेक्ट) प्राप्त करने के लिए (: नींद)' –

2

आप Mocha उपयोग कर रहे हैं, तो कुछ इस तरह काम करेगा:

def setup 
    Kernel.stubs(:sleep) 
end 

def test_my_sleepy_method 
    my_object.take_cat_nap! 
    Kernel.assert_received(:sleep).with(1800) #should take a half-hour paower-nap 
end 

या यदि आप rr उपयोग कर रहे हैं:

def setup 
    stub(Kernel).sleep 
end 

def test_my_sleepy_method 
    my_object.take_cat_nap! 
    assert_received(Kernel) { |k| k.sleep(1800) } 
end 

आप शायद अधिक का परीक्षण नहीं किया जाना चाहिए इकाई परीक्षण के साथ जटिल थ्रेडिंग मुद्दों। हालांकि, एकीकरण परीक्षणों पर, असली Kernel.sleep का उपयोग करें, जो आपको जटिल थ्रेडिंग समस्याओं को हल करने में मदद करेगा।

4

शुद्ध rspec में:

before do 
    Kernel.stub!(:sleep) 
end 

it "should sleep" do 
    Kernel.should_receive(:sleep).with(100) 
    Object.method_to_test #We need to call our method to see that it is called 
end 
+8

स्पष्टीकरण के लिए, क्योंकि यह तुरंत मेरे लिए काम नहीं करता है, आपको कर्नेल को कॉल करना होगा इस तरह नकली करने के लिए, सो जाओ। बस नींद को बुलाकर –

+0

हां, हां, जिस विधि को आप कॉल करते हैं उसमें वह नींद होगी। – nitecoder

0

मैं ठूंठ करने की जरूरत की आवश्यकता होती है और लंबे समय से खोज करने के बाद मैंने पाया कि एक ही तरीका है कि मेरे लिए काम किया भीतर इस

def method_using_sleep 
    sleep 
    sleep 0.01 
end 

it "should use sleep" do 
    @expectations = mock('expectations') 
    @expectations.should_receive(:sleep).ordered.with() 
    @expectations.should_receive(:sleep).ordered.with(0.01) 

    def sleep(*args) 
    @expectations.sleep(*args) 
    end 

    method_using_sleep 
end 
0

मैं काम करने के लिए यहां अन्य समाधान प्राप्त करने में सक्षम नहीं था। रूबी के नए संस्करणों में कुछ और नींद को संभालने के तरीके में कुछ बदल गया है, या कुछ और।

मैं क्या कर रहा था बंदर-पैच ऑब्जेक्ट कक्षा जैसा लगता है कि यह नींद की कॉल प्राप्त करता है। तो मैं बस इस कहा:

class Object 
    def sleep(*args) 
    end 
end 

तो नींद विधि अब कुछ की जगह में कुछ नहीं करता है। यह बेहतर तरीके से मजाक करने का कोई तरीका हो सकता है, लेकिन मुझे संभावित रूप से उपयोग किए जाने वाले प्रत्येक ऑब्जेक्ट के sleep metohd का मज़ाक उड़ाए बिना एक अच्छा समाधान नहीं मिला।

+0

कृपया मेरा समाधान देखें। rspec-mock यहाँ है इसलिए आपको बंदर-पैच नहीं है – Benj

11

जब sleep करने के लिए कॉल एक वस्तु के भीतर नहीं है (उदाहरण के लिए एक रेक कार्य का परीक्षण करते हुए), आपको निम्न एक में ब्लॉक से पहले जोड़ सकते हैं (rspec 3 वाक्य रचना)

allow_any_instance_of(Object).to receive(:sleep)