2012-01-04 13 views
57

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

वस्तु:

describe("The Klass constructor", function() { 
    it("should call its prototype's called_method", function() { 
     spyOn(Klass.prototype, 'called_method'); //.andCallThrough(); 
     var k = new Klass(); 
     expect(Klass.prototype.called_method).toHaveBeenCalled(); 
    }); 
}); 

उत्तर

98

जासूस सीधे:

Klass = function() { 
    this.called_method(); 
}; 

Klass.prototype.called_method = function() { 
    //method to be called in the constructor. 
} 

मैं कल्पना में कुछ इस तरह करना चाहते हैं ऊपर डेव न्यूटन के जवाब के साथ। हालांकि, इस दृष्टिकोण के लिए कुछ किनारे-मामले हैं जिन पर आपको विचार करना चाहिए।

एक और परीक्षण-केस के साथ, डेव के समाधान के लिए एक बदलाव लें:

// production code 
var Klass = function() { 
    this.call_count = 0; 
    this.called_method(); 
}; 
Klass.prototype.called_method = function() { 
    ++this.call_count; 
}; 

// test code 
describe("The Klass constructor", function() { 
    it("should call its prototype's called_method", function() { 
    spyOn(Klass.prototype, 'called_method'); 
    var k = new Klass(); 
    expect(k.called_method).toHaveBeenCalled(); 
    }); 
    it('some other test', function() { 
    var k = new Klass(); 
    expect(k.call_count).toEqual(1); 
    }); 
}); 

दूसरे टेस्ट असफल हो जायेगी क्योंकि पहले टेस्ट में जासूस सेटअप दूसरी विधि में परीक्षण सीमाओं के पार बनी रहती है; call_method कॉल_count में वृद्धि नहीं करता है, इसलिए यह.call_count बराबर नहीं है 1. झूठी सकारात्मकताओं के साथ परिदृश्यों के साथ आना भी संभव है - परीक्षण जो पास नहीं हो सकते हैं।

इस पर, क्योंकि जासूसी बनी हुई है, उतने अधिक क्लास उदाहरण बनाए गए हैं, जितना अधिक मेमोरी ढेर का उपयोग करेगा, क्योंकि जासूस प्रत्येक कॉल को call_method पर रिकॉर्ड करेगा। यह शायद ज्यादातर परिस्थितियों में कोई समस्या नहीं है, लेकिन आपको इसके बारे में अवगत होना चाहिए, बस मामले में।

इस समस्या का एक आसान समाधान यह सुनिश्चित करना होगा कि जासूस को इसका उपयोग करने के बाद हटा दिया गया हो। यह एक सा बदसूरत लग सकता है, लेकिन कुछ इस तरह काम करता है:

// test code 
describe("The Klass constructor", function() { 
    it("should call its prototype's called_method", function() { 
    var spy = jasmine.createSpy('called_method'); 
    var method = Klass.prototype.called_method; 
    Klass.prototype.called_method = spy; 
    var k = new Klass(); 
    expect(spy).toHaveBeenCalled(); 
    Klass.prototype.called_method = method; 
    }); 

[ध्यान दें - एक छोटे से राय खत्म करने के लिए] एक बेहतर समाधान जिस तरह से आप लिखना उत्पादन कोड कोड का परीक्षण करने के आसान बनाने के लिए बदलने के लिए किया जाएगा। एक नियम के रूप में, प्रोटोटाइप पर जासूसी शायद एक कोड-गंध से बचा जा सकता है। कन्स्ट्रक्टर में निर्भरता को तत्काल करने के बजाय, उन्हें इंजेक्ट करें। कन्स्ट्रक्टर में प्रारंभ करने के बजाय, एक उचित init विधि को स्थगित करें।

+3

इसके लिए धन्यवाद। सबसे अच्छा विवरण मैंने पूरे दिन – Subimage

+0

पर देखा है, वहां एक झुकाव था, वहां इसका एक वैध समाधान था। धन्यवाद। – BradGreens

+0

इस दृष्टिकोण के साथ दो समस्याएं हैं। सबसे पहले, यह मेमोरी रिसाव का कारण बनता है - कॉल_स विधि विधि क्लास के सभी भावी उदाहरणों पर जासूसी की जाएगी और जैसे ही अधिक कॉल किए जाएंगे, जासूस की स्मृति खपत बढ़ेगी। दूसरी और अधिक प्रासंगिक रूप से, यह संभावित रूप से कई परीक्षणों का कारण बनता है जो क्लास को एक दूसरे के साथ बातचीत करने के लिए पूछताछ करते हैं, क्योंकि जासूस को पहले से ही बुलाया जाएगा। आपको यह सुनिश्चित करना चाहिए कि जासूस हटा दिया गया है या Klass.prototype.called_method परीक्षण केस के अंत में मूल विधि पर रीसेट हो गया है। – alecmce

11

मोटे तौर पर, मैं सहमत हूं: प्रोटोटाइप पद्धति पर

it('should spy on a method call within the constructor', function() { 
    spyOn(window, 'Klass'); 
    var obj = new Klass(); 
    expect(window.Klass.called_method).toHaveBeenCalled(); 
}); 
+1

+1, अतिरिक्त जानकारी के लिए धन्यवाद। मुझे लगता है कि नीचे "नोट" खंड काफी सब कुछ बताता है; यह लगभग निश्चित है कि इसे परीक्षण के बजाय कहीं और तय किया जाना चाहिए। –

+0

यह जैस्मीन के नवीनतम संस्करणों के साथ काम करता है। –

+0

हाँ, मुझे लगता है कि उन्होंने कुछ समय पहले इस गोचा को बंद कर दिया था। सिद्धांत के मामले के रूप में प्रोटोटाइप पर जासूसी से बचने के लायक अभी भी लायक है। – alecmce

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