2016-01-29 13 views
5

में सेटटाइमआउट और क्लीयरटाइम पर जासूस मैं अपने जैस्मीन परीक्षणों में setTimeout और clearTimeout पर जासूसी करने में सक्षम नहीं हूं, जो कर्म के माध्यम से चल रहे हैं।कर्मा और जैस्मीन

मैं इस

spyOn(window, 'setTimeout').and.callFake(()=>{}); 
spyOn(global, 'setTimeout').and.callFake(()=>{}); 
spyOn(window, 'clearTimeout').and.callThrough(); 

clock = jasmine.clock(); 
clock.install(); 
spyOn(clock, 'setTimeout').and.callThrough(); 

runMyCode(); 

expect(window.setTimeout).toHaveBeenCalled(); // no 
expect(global.setTimeout).toHaveBeenCalled(); // nope 
expect(window.clearTimeout).toHaveBeenCalled(); // no again 
expect(clock.setTimeout).toHaveBeenCalled(); // and no 

हर मामले में के सभी में बदलाव की कोशिश की है, मैं पुष्टि कर सकता है कि setTimeout और clearTimeoutrunMyCode में लागू किया गया है, लेकिन इसके बजाय मैं हमेशा Expected spy setTimeout to have been called.

window के लिए मिलता है, स्पष्ट रूप से ऐसा इसलिए है क्योंकि परीक्षण और धावक (कर्म खिड़की) अलग-अलग फ्रेम में हैं (इसलिए मुझे कुछ अलग क्यों उम्मीद करनी चाहिए)। लेकिन इसके कारण, मैं यह पुष्टि करने का कोई तरीका नहीं देख सकता कि इन वैश्विक कार्यों को लागू किया गया है।

मुझे पता है कि मैं टाइमआउट/अंतराल कॉलबैक का आह्वान करने के लिए jasmine.clock() का उपयोग कर सकता हूं, लेकिन ऐसा लगता है कि मैं setTimeout स्वयं नहीं देख सकता। और यह पुष्टि करते हुए कि clearTimeout कहा जाता है बस संभव नहीं है।

इस बिंदु पर, केवल एक चीज मैं के बारे में सोच सकते हैं अमूर्त का एक अलग परत जोड़ने के लिए setTimeout और clearTimeout रैप करने के लिए या निर्भरता, जो मैंने पहले किया है के रूप में कार्य इंजेक्षन करने के लिए है, लेकिन मुझे लगता है कि अजीब है।

उत्तर

0

एकमात्र - और केवल समाधान मैं इसके लिए पा सकता हूं Rewire (मेरे मामले में, मुझे Rewire-Webpack का उपयोग करने की आवश्यकता है)।

रिवायर आपको वैश्विक तरीकों को बदलने की अनुमति देता है - लेकिन एक बार विधि बदलने के बाद, इसका जासूसी नहीं किया जा सकता है। तो, वास्तव में सफलतापूर्वक toHaveBeenCalledWith का उपयोग करने के लिए, आपको नकली फ़ंक्शन को लपेटना और प्रॉक्सी करना होगा।

var rewire = require('rewire'), 
    myModule = rewire('./path/to/module'); 

describe(function() { 
    var mocks = { 
     setTimeout: function() { return 99: }, 
     clearTimeout: function() {} 
    }; 

    beforeEach(function() { 
     // This will work 
     myModule.__set__('setTimeout', function() { 
      mocks.setTimeout.apply(null, arguments) 
     }) 

     // This will NOT work 
     myModule.__set__('clearTimeout', mocks.clearTimeout) 
    }); 

    it('calls setTimeout', function() { 
     spyOn(mocks, 'setTimeout').and.callThrough(); 
     spyOn(mocks, 'clearTimeout').and.callThrough(); 

     myModule.doSomething(); // this will invoke setTimeout locally 

     expect(mocks.setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 1000); 
     expect(mocks.clearTimeout).toHaveBeenCalledWith(99); // Won't work (see above) 

    }); 
}); 

जाहिर है, इस निश्चित रूप से अगली बार जैस्मीन, Rewire, कर्म काम बंद हो जाएगा, Webpack ... या मौसम ... परिवर्तन (गरर)। यदि यह आपके लिए काम नहीं करता है, तो कृपया एक टिप्पणी छोड़ दें ताकि भविष्य के देवताओं को पता चलेगा।

1

मैं इसे इस तरह काम करने के लिए प्राप्त करने में सक्षम था:

spyOn(window, 'setTimeout'); 
runMyCode(); 
expect(setTimeout).toHaveBeenCalled(); 

बस setTimeout कॉल से 'विंडो' वस्तु को हटा दें।

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