एक वस्तु के बिना एक समारोह पर जासूसी करने के लिए जैस्मीन का उपयोग करना


154

मैं जैस्मीन के लिए नया हूं और अभी इसका इस्तेमाल करना शुरू किया है। मेरे पास बहुत सारे कार्यों के साथ एक लाइब्रेरी जेएस फाइल है जो किसी भी वस्तु से संबद्ध नहीं हैं (यानी वैश्विक हैं)। मैं इन कार्यों की जासूसी कैसे करूँ?

मैंने ऑब्जेक्ट के रूप में विंडो / डॉक्यूमेंट का उपयोग करने की कोशिश की, लेकिन स्पाई ने काम नहीं किया, भले ही फ़ंक्शन को बुलाया गया था। मैंने इसे एक नकली वस्तु में लपेटने की कोशिश भी की:

var fakeElement = {};
fakeElement.fakeMethod = myFunctionName;
spyOn(fakeElement, "fakeMethod");

और के साथ परीक्षण

expect(fakeElement.fakeMethod).toHaveBeenCalled();

यह काम नहीं करता है क्योंकि जासूस ने काम नहीं किया

जवाबों:


155

यदि आप अपने कार्य को परिभाषित कर रहे हैं:

function test() {};

फिर, यह इसके बराबर है:

window.test = function() {}  /* (in the browser) */

इसलिए spyOn(window, 'test') काम करना चाहिए।

यदि ऐसा नहीं है, तो आपको भी सक्षम होना चाहिए:

test = jasmine.createSpy();

यदि उनमें से कोई भी काम नहीं कर रहा है, तो आपके सेटअप के साथ कुछ और चल रहा है।

मुझे नहीं लगता fakeElementकि पर्दे के पीछे जो चल रहा है उसकी वजह से आपकी तकनीक काम करती है। मूल GlobalMethod अभी भी उसी कोड को इंगित करता है। जासूसी क्या करता है यह प्रॉक्सी है, लेकिन केवल एक वस्तु के संदर्भ में। यदि आप अपना परीक्षण कोड फर्जी के माध्यम से कॉल करने के लिए प्राप्त कर सकते हैं तो यह काम करेगा, लेकिन तब आप वैश्विक फोंस को छोड़ पाएंगे।


2
इसने काम कर दिया! मुझे लगता है कि मैं पहले जो त्रुटि कर रहा था वह यह था कि मैं जासूसी को विधि के बजाय विधि () के साथ बुला रहा था। धन्यवाद!
Chetter Hummin

3
मुझे 'विंडो' असाइन नहीं किए जाने के कारण हमारे स्वचालन के भाग के रूप में परीक्षणों को चलाने के लिए चुतजाह का उपयोग करके स्पाईऑन (विंडो, 'टेस्ट') का उपयोग करने में कुछ समस्याएँ आई हैं। इसके आस-पास jasmine.createSpy () का उपयोग करना।
हेनर्स

7
jasmine.createSpy () ने मेरे लिए पूरी तरह से काम किया। धन्यवाद!
dplass

1
इस्तेमाल किया test = jasmine.createSpy();AngularJS पर जासूसी करने के लिए $anchroScrollपूरी तरह से काम किया
एडगर मार्टिनेज

1
किसी कारण से मुझे काम करने का कोई तरीका नहीं मिल सकता है, लेकिन यह पूरी तरह से संभव हो सकता है कि ऐसा इसलिए है क्योंकि मैं एक मौजूदा विंडो फ़ंक्शन का मजाक उड़ा रहा हूं; $window.open(url, '_blank');एक नया टैब खोलने के इरादे से (या ब्राउज़र सेटअप के आधार पर विंडो)। मुझे यह सुनिश्चित करने के बारे में क्या होना चाहिए कि यह इस फ़ंक्शन को कॉल कर रहा है और पुष्टि कर रहा है कि यह ब्राउज़र की परवाह किए बिना सही यूआरएल पर नेविगेट कर रहा है?
CSS

71

टाइपस्क्रिप्ट उपयोगकर्ता:

मुझे पता है कि ओपी ने जावास्क्रिप्ट के बारे में पूछा था, लेकिन इस प्रकार आने वाले किसी भी टाइपस्क्रिप्ट उपयोगकर्ता के लिए जो एक आयातित फ़ंक्शन पर जासूसी करना चाहते हैं, यहां आप क्या कर सकते हैं।

परीक्षण फ़ाइल में, इस से फ़ंक्शन के आयात को परिवर्तित करें:

import {foo} from '../foo_functions';

x = foo(y);

इसके लिए:

import * as FooFunctions from '../foo_functions';

x = FooFunctions.foo(y);

तब आप जासूसी कर सकते हैं FooFunctions.foo:)

spyOn(FooFunctions, 'foo').and.callFake(...);
// ...
expect(FooFunctions.foo).toHaveBeenCalled();

3
टाइपस्क्रिप्ट संकेत के लिए धन्यवाद। ईएस 6 / बैबेल के लिए समान होना चाहिए, लेकिन मैंने इसकी कोशिश नहीं की है।
होजेबेल

1
लगता है कि यह केवल उर्फ FooFunctions के साथ फ़ंक्शन को कॉल करने पर काम करता है । मेरे पास एक फंक्शन बार () है जो एक फैक्ट्री है जो बाज () को लौटाती है और उस बाज () कॉल फू () को टेस्ट करना चाहती है। यह पद्धति उस परिदृश्य में काम नहीं करती है।
रिचर्ड मैट्सन

4
यह तब काम करेगा जब उपनाम को foo_functions के अंदर ले जाया export const FooFunctions = { bar, foo }; जाता है और परीक्षण में आयात हो जाता है import { FooFunctions } from '../foo_functions'. , हालाँकि, उपनाम को अभी भी स्पष्ट रूप से foo_functions के निजी कार्यान्वयन के लिए उपयोग किया जाना चाहिए। const result = FooFunctions.foo(params)// जासूसी रिपोर्ट कॉल const result = foo(params)// जासूसी रिपोर्ट कोई कॉल नहीं
रिचर्ड मैटसन

2
एक जादू की तरह काम किया! धन्यवाद, आपने मुझे बहुत समय बचाया!
SrAxi

1
यह अब काम नहीं कर रहा हैError: <spyOn> : parseCookie is not declared writable or has no setter
लिंग वु

42

2 विकल्प है जो मैं उपयोग करता हूं (चमेली 2 के लिए)

यह एक बहुत स्पष्ट नहीं है क्योंकि ऐसा लगता है कि फ़ंक्शन वास्तव में एक नकली है।

test = createSpy().and.callFake(test); 

दूसरी अधिक क्रिया, अधिक स्पष्ट, और "क्लीनर":

test = createSpy('testSpy', test).and.callThrough();

-> दूसरा तर्क देखने के लिए चमेली स्रोत कोड


यह थोड़ा अधिक समझ में आता है और सफलता के साथ नकल करने के लिए इसे बहुत दूर तोड़ देता है। मुझ से +1। धन्यवाद, C:00
CSS

9

एक बहुत ही सरल तरीका:

import * as myFunctionContainer from 'whatever-lib';

const fooSpy = spyOn(myFunctionContainer, 'myFunc');

1
import * as saveAsFunctions from 'file-saver';
..........
....... 
let saveAs;
            beforeEach(() => {
                saveAs = jasmine.createSpy('saveAs');
            })
            it('should generate the excel on sample request details page', () => {
                spyOn(saveAsFunctions, 'saveAs').and.callFake(saveAs);
                expect(saveAsFunctions.saveAs).toHaveBeenCalled();
            })

इसने मेरे लिए काम किया।


4
कृपया अपने उत्तर में स्पष्टीकरण जोड़ें, कोड अपने आप में यह सवाल पूछने वाले व्यक्ति के लिए मददगार नहीं है कि वे समझ नहीं पा रहे हैं कि क्या हो रहा है।
chevybow

0

मेरा उत्तर @FlavorScape में थोड़ा भिन्न है कि मेरे पास आयातित मॉड्यूल में एक एकल (डिफ़ॉल्ट निर्यात) फ़ंक्शन था, मैंने किया:

import * as functionToTest from 'whatever-lib';

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