2014-12-06 12 views
9

मैं वर्तमान में SinonJS का उपयोग करके अपनी कोणीय सेवा का परीक्षण करने की कोशिश कर रहा हूं, लेकिन एक समस्या में भाग रहा हूं और उम्मीद कर रहा था कि यह संभवतः कुछ क्यों हो सकता है कि यह क्यों हो रहा है। मैंने समस्या को स्पष्ट करने के लिए अपने वर्तमान प्रोजेक्ट का पुनर्निर्माण किया है।कोणीय यूनिट परीक्षण - एक ही सेवा में मॉकिंग विधियों/बंदियों

मैं भी एक DEMO

प्रदान की है मैं एक सेवा, peopleService है:

(function(){ 

    angular.module('myApp') 
    .factory('peopleService', peopleService); 

    peopleService.$inject = ['$q']; 

    function peopleService ($q){ 
     var people = ['Homer', 'Marge', 'Bart', 'Lisa', 'Maggie']; 

     // in actual project, this makes an http request 
     function getFamily() { 
     return people; 
     } 

     function getAdults(){ 
     var family = getFamily(); 
     return family.filter(function (person){ 
      return person === 'Homer' || person === 'Marge'; 
     }); 
     } 

     return { 
     getFamily: getFamily, 
     getAdults: getAdults 
     } 
    } 

}()); 

इस सेवा में, मेरा विधि getAdultsgetFamily का उपयोग करता है, परिणाम फ़िल्टर, और डेटा देता है।

मेरे यूनिट परीक्षण में, मैं getFamily पर नकल करने की कोशिश कर रहा हूं और देख रहा हूं कि वह विधि कहां जा रही है या नहीं। अब इस जगह है जहाँ समस्या में प्रस्तुत करता है ...

पहली बात मैंने कोशिश की विधि को छोटा किया गया था और वर्तमान पद्धति को अधिलेखित, इसलिए जैसे:

beforeEach(function(){ 
    module('myApp'); 

    inject(function (_peopleService_){ 
    peopleService = _peopleService_; // get the service 
    sinon.stub(peopleService, 'getFamily'); // stub it 
    }); 
}); 

मैं तो getAdults कॉल चाहे getFamily परीक्षण करने के लिए जाना विधि:

it('getAdults should call "getFamily" once', function(){ 
    peopleService.getAdults(); 
    expect(peopleService.getFamily.calledOnce).toBe(true); 
}); 

परीक्षण विफल रहता है और टोंटदार विधि कहा जाता है नहीं है ...

मैं डिबग और टी पता लगाना हालांकि समारोह टोपी वास्तव में बदल गया है:

enter image description here

मेरे प्रारंभिक सोचा था: enter image description here

सेवा अभी भी क्या विधि हुआ करता था जब सेवा बनाया गया था के लिए एक संदर्भ (बंद) रखती है मैंने विधि को सही तरीके से नहीं दबाया। इसके बाद मैंने $provide ($provide.value) के साथ-साथ $injector decorator का उपयोग करके विधि को ओवरराइट करने का प्रयास किया और मुझे एक ही परिणाम (मूल विधि पर बंद बंद) प्राप्त हुआ।

इस के लिए एक समाधान this उपयोग करने के लिए होगा:

function getAdults(){ 
    var family = this.getFamily(); // <-- by using this.getFamily would reference the mock 
    return family.filter(function (person){ 
     return person === 'Homer' || person === 'Marge'; 
    }); 
    } 

हालांकि, मुझे समझ नहीं आता क्यों मैं यह करने के लिए है।

संक्षेप में, किसी को पता है:

  • एक इकाई परीक्षण में this
  • उपयोग करने के लिए एक बंद चर बाहर उपहास करने के लिए कैसे बिना एक ही सेवा में किसी अन्य विधि का उपहास करने के लिए कैसे

आपके समय के लिए बहुत बहुत धन्यवाद।

+0

लगता है अपने plunker अब उपलब्ध नहीं है – sam

उत्तर

5

जब आप किसी ऑब्जेक्ट पर किसी विधि को दबाते हैं, तो उस ऑब्जेक्ट की प्रॉपर्टी प्रॉपर्टी ओवरराइड होती है, न कि उस मूल कार्य को संदर्भित करता है।

उदाहरण के लिए, इस कोड:

function myFunction() {}; 
var myObj = { prop: myFunction }; 

myObj.prop === myFunction; // true 
myObj.prop = 'changed'; 

typeof myFunction === 'function'; // true 
myObj.prop === myFunction; // false 

myObj.prop बदलने मूल कार्य परिवर्तन नहीं किया, myFunction अभी भी अपने आप में ही मौजूद है। myObj.prop, हालांकि, myFunction पर इसका संदर्भ खो गया है। अगर यह साइनऑन दुनिया में था, तो बस स्टबिंग ने myObj.prop के स्टब ऑब्जेक्ट में संदर्भ बदल दिया।

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

angular.module('myApp') 
    .factory('peopleService', peopleService); 

peopleService.$inject = ['$q']; 

function peopleService ($q){ 
    var service = { 
    getFamily: getFamily, 
    getAdults: getAdults 
    }; 

    return service; 

    function getFamily() { 
    // ... 
    } 

    function getAdults(){ 
    var family = service.getFamily(); // <-- reference service.getFamily() 
    // ... 
    } 
} 
+0

मुझे लगता है कि इस सवाल का जवाब इनाम मिलना चाहिए, यह बहुत स्पष्ट है और पूरा हो गया है – sam

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