2015-10-15 7 views
29

मैं जैस्मीन का उपयोग कर गेटर संपत्ति पर जासूसी कैसे कर सकता हूं?मैं जैस्मीन का उपयोग कर गेटर संपत्ति पर जासूसी कैसे कर सकता हूं?

var o = { get foo() {}, }; 

spyOn(o, 'foo').and.returnValue('bar'); // Doesn't work. 

यह भी AFAICT काम नहीं करता:

spyOn(Object.getOwnPropertyDescriptor(o, 'foo'), 'get').and.returnValue('bar'); 
+0

[इसी तरह के प्रश्न] (http://stackoverflow.com/questions/31338197) पर चर्चा से, आप नहीं कर सकते। गेटर्स और सेटर्स को मानक तरीकों के रूप में नहीं माना जाता है (उदाहरण के लिए उन्हें फ़ंक्शन के रूप में शामिल करने की आवश्यकता नहीं है।) – Mathletics

+0

हो सकता है कि आप विभिन्न ऑब्जेक्ट राज्यों के आधार पर पुनर्प्राप्त मूल्य के परिणाम का परीक्षण कर सकें। –

+1

यहां टिप्पणियों के आधार पर, यह स्पष्ट रूप से कार्यान्वित नहीं किया गया है, लेकिन यह सैद्धांतिक रूप से असंभव नहीं है। कारण 'spyOn (Object.getOwnPropertyDescriptor (o,' foo '),' get ')' काम नहीं करता है क्योंकि 'spyOn' ऑब्जेक्ट की प्रॉपर्टी को एक नया फ़ंक्शन बनने के लिए फिर से लिखता है जो मौजूदा फ़ंक्शन को लपेटता है। 'GetOwnPropertyDescriptor' द्वारा लौटाई गई संपत्ति डिस्क्रिप्टर ऑब्जेक्ट को बदलना वास्तविक संपत्ति को बदलने के लिए कुछ भी नहीं करता है। हालांकि, आप सेटर/गेटर्स का पता लगाने के लिए जैस्मीन बदल सकते हैं और वास्तव में 'DefineProperty' के साथ संपत्ति को फिर से लिख सकते हैं। हो सकता है कि एक सुविधा अनुरोध खोलें, यदि यह आपके लिए महत्वपूर्ण है? – apsillers

उत्तर

19

जैस्मीन 2.6 के बाद से, यह spyOnProperty साथ संभव हो गया है। foo संपत्ति के लिए accessors पर जासूसी करने के लिए, कार्य करें:

spyOnProperty(o, 'foo') 

यह आपको एक जासूस समारोह के साथ एक्सेसर गुण के लिए set और/या get एक्सेसर कार्यों को बदलने के लिए अनुमति देता है। आप यह निर्दिष्ट या set या get केवल एक तिहाई तर्क के रूप में कर सकते हैं:

spyOnProperty(o, 'foo', 'get') 

आप किसी पुराने संस्करण का उपयोग कर फंस रहे हैं और किसी कारण से अपग्रेड नहीं कर सकते हैं, तो आप कोड के अपने स्थानीय प्रतिलिपि में pull request that added this feature विलय करने के लिए सक्षम हो सकता है ।

+1

क्या मैं यह सोचने में सही हूं कि 'accessor' को' कॉन्फ़िगर करने योग्य: सत्य 'के रूप में सेट नहीं किया गया है तो यह असफल हो जाएगा? जिसका अर्थ है कि आप भाग्य से बाहर हैं यदि आप किसी तीसरे पक्ष के एक्सेसर पर जासूसी करने की कोशिश कर रहे हैं जहां इसे निर्दिष्ट नहीं किया गया है? – james

+0

@james मुझे लगता है कि एक गैर-कॉन्फ़िगर करने योग्य संपत्ति (चाहे एक्सेसर-आधारित या पारंपरिक डेटा प्रॉपर्टी) जास्मीन द्वारा कभी भी जासूसी नहीं की जा सकती। (मैं 100% नहीं हूं और इस समय परीक्षण नहीं कर सकता, लेकिन सभी जासूसी संपत्ति प्रतिस्थापन पर आधारित है।) – apsillers

0

मैं नहीं मानता कि आप ही टिककर खेल पर जासूसी कर सकते हैं। गेटटर का मुद्दा यह है कि यह वास्तव में एक संपत्ति की तरह कार्य करता है, तो जैस्मीन इस पर जासूसी करने में सक्षम कैसे होगा जब इसे किसी फ़ंक्शन की तरह कभी नहीं कहा जाता है बल्कि इसे किसी संपत्ति की तरह एक्सेस किया जाता है।

एक कामकाज के रूप में, आप अपने गेटर को इसके बजाय एक और फ़ंक्शन और जासूसी कर सकते हैं।

var o = { 
    _foo: function(){ 
     return 'foo'; 
    }, 
    get foo(){ 
     return this._foo(); 
    } 
}; 

spyOn(o, '_foo').and.returnValue('bar'); 
5

मैं @apsillers प्रतिक्रिया से प्रेरणा ली और निम्नलिखित सहायक लिखा था (प्रोप की आवश्यकता है जैसा कि ऊपर उल्लेख विन्यास होने के लिए)

let activeSpies = []; 
let handlerInstalled = false; 

function afterHandler() { 
    activeSpies.forEach(({ obj, prop, descriptor }) => Object.defineProperty(obj, prop, descriptor)); 
    activeSpies = []; 
} 


export function spyOnGetter(obj, prop) { 
    const env = jasmine.getEnv(); 
    const descriptor = Object.getOwnPropertyDescriptor(obj, prop); 
    const spy = jasmine.createSpy(`${prop} spy`); 
    const copy = Object.assign({}, descriptor, { get: spy }); 
    Object.defineProperty(obj, prop, copy); 
    activeSpies.push({ 
     obj, 
     prop, 
     descriptor, 
    }); 

    if (!handlerInstalled) { 
     handlerInstalled = true; 
     env.afterEach(() => afterHandler()); 
    } 
    return spy; 
} 

और यह इतनी की तरह इस्तेमाल किया जा सकता है:

import { spyOnGetter } from spyExtra; 
it('tests the thing',() => { 
    spyOnGetter(myObj, 'myProp').and.returnValue(42); 
    expect(myObj.myProp).toBe(42); 
}); 

आशा येह काम का है!

19

फरवरी 2017 में, वे इस सुविधा को जोड़ने एक जनसंपर्क विलय कर दिया, वे

अप्रैल 2017 में इसे जारी किया तो टिककर खेल पर आप का उपयोग/setters जासूसी करने के लिए: const spy = spyOnProperty(myObj, 'myGetterName', 'get'); जहां myObj अपने उदाहरण है, 'myGetterName' है उस श्रेणी का नाम आपकी कक्षा में get myGetterName() {} के रूप में परिभाषित किया गया है और तीसरा पैरामीटर get या set है।

आप उसी दावे का उपयोग कर सकते हैं जिसका उपयोग आप पहले से ही spyOn के साथ बनाई गई जासूसों के साथ करते हैं।

तो आप कर सकते हैं उदाहरण के लिए:

const spy = spyOnProperty(myObj, 'myGetterName', 'get'); // to stub and return nothing. Just spy and stub. 
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.returnValue(1); // to stub and return 1 or any value as needed. 
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.callThrough(); // Call the real thing. 

यहाँ GitHub स्रोत कोड जहां इस विधि उपलब्ध है अगर आप रुचि रखते हैं में लाइन है।

https://github.com/jasmine/jasmine/blob/7f8f2b5e7a7af70d7f6b629331eb6fe0a7cb9279/src/core/requireInterface.js#L199

चमेली 2.6 के साथ मूल प्रश्न का उत्तर देना,।1, क्या तुम करोगी:

var o = { get foo() {} }; 
spyOnProperty(o, 'foo', 'get').and.returnValue('bar'); 
+0

यह सहायक है, लेकिन मुझे लगता है कि आपका मतलब है 'spyOnProperty', 'spyOnAttribute' नहीं, सही? – kpup

+0

निश्चित रूप से। मैंने उस अंतिम पंक्ति को छोड़कर हर जगह spyOnProperty लिखा था। मैंने जवाब अपडेट किया। धन्यवाद! – Juan

0

आप यह कर सकते हैं अगर आप नवीनतम चमेली (2.6.1)

const getSpy = jasmine.createSpy().and.returnValue('bar') 
Object.defineProperty(o, 'foo', { get: getSpy }); 

defineProperty के लिए दस्तावेज़ का उपयोग करने में असमर्थ हैं, here

3

मैं सबसे अच्छा लगता है spyOnProperty का उपयोग करना है। यह 3 गुणों की अपेक्षा करता है और आपको get या set को तीसरी संपत्ति के रूप में पास करने की आवश्यकता है।

spyOnProperty(o, 'foo', 'get').and.returnValue('bar'); 
संबंधित मुद्दे