कैसे जैस्मीन के साथ एक मूल्य संपत्ति (एक विधि के बजाय) जासूसी करने के लिए


115

जैस्मीन का spyOnतरीका बदलने के लिए अच्छा है, लेकिन क्या किसी वस्तु के लिए मूल्य संपत्ति (एक विधि के बजाय) बदलने का कोई तरीका है? कोड नीचे की तरह हो सकता है:

spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);

जवाबों:


97

फरवरी 2017 में, उन्होंने इस सुविधा को जोड़ते हुए एक पीआर का विलय कर दिया, वे अप्रैल 2017 में जारी किए गए।

इसलिए 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 के साथ, आप:

const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();

7
मैं ऐसा कैसे किया जाए, तो valueAएक Observableया Subject? मैं मिल रहा हूँProperty valueA does not have access type get
Ka Mok

4
शायद इसका मतलब है कि आप उस संपत्ति पर इसका इस्तेमाल नहीं कर सकते। SpyOnProperty getOwnPropertyDescriptor का उपयोग कर रहा है और जाँच कर रहा है कि क्या एक्सेस टाइप मिलता है | उस प्रॉपर्टी डिस्क्रिप्टर के लिए सेट मौजूद है। आपको जो त्रुटि हो रही है, वह इसलिए है क्योंकि संपत्ति का विवरणकर्ता सेट नहीं है या उस संपत्ति के लिए प्राप्त करें जिसे आप जासूसी करने की कोशिश कर रहे हैं। जैस्मीन ऐसा करती है: const डिस्क्रिप्टर = Object.getOwnPropertyDescriptor ... if ((डिस्क्रिप्टर [accessType]) {// एरर फेंकी जाती है}
Juan

तो, स्पष्ट गटर और सेटर विधियों के बिना किसी संपत्ति की जासूसी करने का कोई तरीका नहीं है? जासूसी करने के लिए एक संपत्ति का इस्तेमाल किया जाता है।
डोमिनिक

: @Dominik यहाँ मैं सभी एक लंबे लेख में इस से संबंधित हुड सामान के नीचे लिखा था medium.com/@juanlizarazo/...
जुआन

1
@ मैथ्यू यह एक अच्छा दावा नहीं है क्योंकि यह सिर्फ यह बताता है कि हम पहले से ही जानते हैं कि हमने जासूस को क्या करने के लिए कहा था, लेकिन यह सिर्फ वही है जो वे पूछ रहे थे और उनका वही प्रश्न कोड स्निपेट (_ (ツ) _ / point बिंदु उनका सवाल था कि किसी संपत्ति की जासूसी कैसे की जाए और उनका विशिष्ट उदाहरण नहीं है।
जुआन

12

किसी भी कारण से आप इसे सीधे वस्तु पर नहीं बदल सकते हैं? ऐसा नहीं है कि जावास्क्रिप्ट किसी वस्तु पर किसी संपत्ति की दृश्यता को लागू करता है।


1
spyOnस्पष्ट रूप से उपयोग करना इंगित करता है कि मैं कुछ नकली चाहता हूं, जबकि मैं सीधे संपत्ति सेट करता हूं निहितार्थ इंगित करता है कि मैं कुछ नकली चाहता हूं, और मुझे यकीन नहीं है कि कोई अन्य व्यक्ति यह समझ जाएगा कि मैं कुछ पढ़ रहा हूं जब वह कोड पढ़ रहा हो। अन्य मामला यह है कि मैं वस्तु के आंतरिक व्यवहार को बदलना नहीं चाहता, उदाहरण के लिए अगर मैं किसी सरणी के लिए लंबाई संपत्ति को बदल देता हूं, तो सरणी को छंटनी की जाती है, इसलिए एक नकली बेहतर होगा
Shuping

@ शूपिंग, इस मामले में, आप मजाक नहीं करेंगे। तुम जो पूरी तरह से ठीक है stubbing होगा। आप केवल परीक्षण के अंदर "व्यवहार बदल रहे हैं" जो आप के साथ हासिल करने की कोशिश कर रहे थे spyOn
फाबियो मिल्हेइरो

संभवतः आप रनटाइम ऑब्जेक्ट प्रोटोटाइप पर जासूसी करना चाहते हैं ताकि यह सुनिश्चित हो सके कि संपत्ति रनटाइम में मौजूद होगी। spyOnयदि संपत्ति मौजूद नहीं है तो जैस्मिन परीक्षण में विफल रहता है।
sennett

2
एक उदाहरण window.sessionStorage को सेट करना या हटाना है:TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
क्रिस सैटिंगर

2
जावास्क्रिप्ट में एक वस्तु संपत्ति को पुन: सौंपना हमेशा संभव नहीं होता है
Renaud

12

जैस्मीन में वह कार्यक्षमता नहीं है, लेकिन आप एक साथ प्रयोग करके कुछ हैक कर सकते हैं Object.defineProperty

आप एक गेटर फ़ंक्शन का उपयोग करने के लिए अपने कोड को रीफ़ैक्टर कर सकते हैं, फिर गेटर पर जासूसी कर सकते हैं।

spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);

हां, अब मैं यही कर सकता हूं।
Shuping

4
चमेली 2 के लिए यह है:and.returnValue(1)
jtzero

9

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

उदाहरण

const div = fixture.debugElement.query(By.css('.ellipsis-overflow'));
// now mock properties
spyOnProperty(div.nativeElement, 'clientWidth', 'get').and.returnValue(1400);
spyOnProperty(div.nativeElement, 'scrollWidth', 'get').and.returnValue(2400);

यहाँ मैं की स्थापना कर रहा हूँ getकी clientWidthकी div.nativeElementवस्तु।


6

यदि आप ES6 (बैबल) या टाइपस्क्रिप्ट का उपयोग कर रहे हैं तो आप एक्सेस का उपयोग करके और एक्सेस सेट करके संपत्ति को स्टब कर सकते हैं

export class SomeClassStub {
  getValueA = jasmine.createSpy('getValueA');
  setValueA = jasmine.createSpy('setValueA');
  get valueA() { return this.getValueA(); }
  set valueA(value) { this.setValueA(value); }
}

फिर अपने परीक्षण में आप देख सकते हैं कि संपत्ति किसके साथ सेट है:

stub.valueA = 'foo';

expect(stub.setValueA).toHaveBeenCalledWith('foo');

या, यदि परीक्षण के तहत गेटर्स कक्षा का हिस्सा हैं, तो स्टब्स को एक उपवर्ग में इंजेक्ट किया जा सकता है।
ccprog

6

ऐसा करने का सही तरीका संपत्ति पर जासूसी के साथ है, यह आपको एक विशिष्ट मूल्य के साथ एक वस्तु पर संपत्ति का अनुकरण करने की अनुमति देगा।

const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();

1

मान लीजिए कि इस तरह की एक विधि है जिसे परीक्षण की आवश्यकता srcहै छोटी छवि की संपत्ति को जांचने की आवश्यकता है

function reportABCEvent(cat, type, val) {
                var i1 = new Image(1, 1);
                var link = getABC('creosote');
                    link += "&category=" + String(cat);
                    link += "&event_type=" + String(type);
                    link += "&event_value=" + String(val);
                    i1.src = link;
                }

नीचे दी गई स्पाईऑन () "नई छवि" के कारण परीक्षण से फर्जी कोड प्राप्त किया जा सकता है, जबकि स्पाईऑन कोड एक ऐसी वस्तु देता है जिसमें केवल src संपत्ति होती है

जैसा कि चर "हुक" को स्पाईऑन में नकली कोड में दिखाई दे रहा है और बाद में "रिपोर्टअब्वेंट" भी कहा जाता है

describe("Alphabetic.ads", function() {
    it("ABC events create an image request", function() {
    var hook={};
    spyOn(window, 'Image').andCallFake( function(x,y) {
          hook={ src: {} }
          return hook;
      }
      );
      reportABCEvent('testa', 'testb', 'testc');
      expect(hook.src).
      toEqual('[zubzub]&arg1=testa&arg2=testb&event_value=testc');
    });

यह चमेली 1.3 के लिए है, लेकिन 2.0 पर काम कर सकता है अगर "andallallake" को 2.0 नाम में बदल दिया जाए


1

मैं एक केंडल ग्रिड का उपयोग कर रहा हूं और इसलिए कार्यान्वयन को एक गटर विधि में नहीं बदल सकता, लेकिन मैं इसके चारों ओर परीक्षण करना चाहता हूं (ग्रिड का मजाक उड़ा रहा हूं) और ग्रिड का परीक्षण नहीं कर रहा हूं। मैं एक जासूस वस्तु का उपयोग कर रहा था, लेकिन यह संपत्ति का समर्थन नहीं करता है इसलिए मैं ऐसा करता हूं:

    this.$scope.ticketsGrid = { 
        showColumn: jasmine.createSpy('showColumn'),
        hideColumn: jasmine.createSpy('hideColumn'),
        select: jasmine.createSpy('select'),
        dataItem: jasmine.createSpy('dataItem'),
        _data: []
    } 

यह थोड़ा लंबा है लेकिन यह एक इलाज का काम करता है


0

मैं यहाँ पार्टी के लिए थोड़ा लेट हूँ लेकिन मुझे पता है कि,

आप सीधे कॉल ऑब्जेक्ट तक पहुंच सकते हैं, जो आपको प्रत्येक कॉल के लिए चर दे सकता है

expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)

-3

आप वेरिएबल को मॉक नहीं कर सकते हैं लेकिन आप इसके लिए गेट्टर फंक्शन बना सकते हैं और उस तरीके को अपनी अटकल फाइल में मॉक कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.