2012-01-16 11 views
58

प्रोग्रामिंग के रूप में एक जैस्मीन परीक्षण सूट में जासूस को हम कैसे साफ़ कर सकते हैं? धन्यवाद।हम जैस्मीन में प्रोग्रामेटिक रूप से जासूसी कैसे साफ़ कर सकते हैं?

beforeEach(function() { 
    spyOn($, "ajax").andCallFake(function(params){ 
    }) 
}) 

it("should do something", function() { 
    //I want to override the spy on ajax here and do it a little differently 
}) 
+4

निश्चित रूप से आपने सही "सही" उत्तर चुना है? – hgoebl

+0

जैस्मीन 2.0 के रूप में ["एक जासूस केवल 'वर्णन' या 'यह' ब्लॉक में मौजूद है जिसमें इसे परिभाषित किया गया है, और प्रत्येक spec के बाद हटा दिया जाएगा।"] (Https://jasmine.github.io/2.0/ परिचय.html # सेक्शन-जासूस) – AJP

उत्तर

7

मैं अगर इसकी एक अच्छा विचार यकीन नहीं है, लेकिन आप पूरी तरह गलत करने के लिए समारोह पर isSpy ध्वज सेट कर सकते हैं:

describe('test', function() { 
    var a = {b: function() { 
    }}; 
    beforeEach(function() { 
     spyOn(a, 'b').andCallFake(function(params) { 
      return 'spy1'; 
     }) 
    }) 
    it('should return spy1', function() { 
     expect(a.b()).toEqual('spy1'); 
    }) 

    it('should return spy2', function() { 
     a.b.isSpy = false; 
     spyOn(a, 'b').andCallFake(function(params) { 
      return 'spy2'; 
     }) 
     expect(a.b()).toEqual('spy2'); 
    }) 

}) 

लेकिन शायद इसकी एक बेहतर विचार के लिए एक नया सूट बनाने के लिए इस मामले में जहां आपको अपने जासूस से दूसरे व्यवहार की आवश्यकता है।

+2

परफेक्ट एंड्रियास। बस मैं यह चाहता हूं। यदि आप बाद में यह पता लगाने के लिए कि यह एक अच्छा विचार है या नहीं। कृपया मुझे बताओ। धन्यवाद। +1 –

+0

यह एक अच्छा विचार नहीं है, मेरा जवाब देखें। – FilmJ

+0

@ एंड्रियास बहुत बहुत धन्यवाद! वास्तव में मुझे क्या चाहिए ... – zbynour

36

मुझे लगता है कि क्या .reset() के लिए है:

spyOn($, 'ajax'); 

$.post('http://someUrl', someData); 

expect($.ajax).toHaveBeenCalled(); 

$.ajax.calls.reset() 

expect($.ajax).not.toHaveBeenCalled(); 
+8

देखें, इसलिए यदि आप डिफ़ॉल्ट व्यवहार को पुनर्स्थापित करना चाहते हैं तो यह सब ट्रैकिंग स्थिति को रीसेट कर देगा, यह मदद नहीं करेगा। – FilmJ

+14

ध्यान दें कि यह जैस्मीन 2 में 0 mySpy.calls.reset() 'में बदल गया है। –

16

तो जासूस चश्मा के बीच स्वचालित रूप से रीसेट कर रहे हैं।

यदि आप एक beforeEach() भीतर andCallFake() उपयोग करना और फिर जबरन एक कल्पना के भीतर इसे बदलने के लिए (जो की संभावना है कारण है कि यह ऐसा करने से रोकने की कोशिश करता है) प्रयास आप वास्तव में मूल कार्य के "बहाली" के लाभ नहीं मिलता है ।

तो सावधान रहना, अपने जासूस ऐसे jQuery के रूप में एक वैश्विक वस्तु पर स्थापित किया जा रहा है, खासकर अगर।

प्रदर्शन:

var a = {b:function() { return 'default'; } }; // global scope (i.e. jQuery) 
var originalValue = a.b; 

describe("SpyOn test", function(){ 
    it('should return spy1', function(){ 
    spyOn(a, 'b').andCallFake(function(params) { 
     return 'spy1'; 
    }) 
    expect(a.b()).toEqual('spy1'); 
    }); 

    it('should return default because removeAllSpies() happens in teardown', function(){ 
    expect(a.b()).toEqual('default'); 
    }); 


    it('will change internal state by "forcing" a spy to be set twice, overwriting the originalValue', function(){ 
    expect(a.b()).toEqual('default'); 

    spyOn(a, 'b').andCallFake(function(params) { 
     return 'spy2'; 
    }) 
    expect(a.b()).toEqual('spy2'); 

    // This forces the overwrite of the internal state 
    a.b.isSpy = false; 
    spyOn(a, 'b').andCallFake(function(params) { 
     return 'spy3'; 
    }) 
    expect(a.b()).toEqual('spy3'); 

    }); 

    it('should return default but will not', function(){ 
    expect(a.b()).toEqual('default'); // FAIL 

    // What's happening internally? 
    expect(this.spies_.length).toBe(1); 
    expect(this.spies_[0].originalValue).toBe(originalValue); // FAIL 
    }); 

}); 

describe("SpyOn with beforeEach test", function(){ 
    beforeEach(function(){ 
    spyOn(a, 'b').andCallFake(function(params) { 
     return 'spy1'; 
    }) 
    }) 

    it('should return spy1', function(){ 
    // inspect the internal tracking of spies: 
    expect(this.spies_.length).toBe(1); 
    expect(this.spies_[0].originalValue).toBe(originalValue); 

    expect(a.b()).toEqual('spy1'); 
    }); 

    it('should return spy2 when forced', function(){ 
    // inspect the internal tracking of spies: 
    expect(this.spies_.length).toBe(1); 
    expect(this.spies_[0].originalValue).toBe(originalValue); 

    // THIS EFFECTIVELY changes the "originalState" from what it was before the beforeEach to what it is now. 
    a.b.isSpy = false; 
    spyOn(a, 'b').andCallFake(function(params) { 
     return 'spy2'; 
    }) 
    expect(a.b()).toEqual('spy2'); 
    }); 

    it('should again return spy1 - but we have overwritten the original state, and can never return to it', function(){ 
    // inspect the internal tracking of spies: 
    expect(this.spies_.length).toBe(1); 
    expect(this.spies_[0].originalValue).toBe(originalValue); // FAILS! 

    expect(a.b()).toEqual('spy1'); 
    }); 
}); 

// If you were hoping jasmine would cleanup your mess even after the spec is completed... 
console.log(a.b == originalValue) // FALSE as you've already altered the global object! 
+0

मैं यह पता लगाने की कोशिश कर रहा था कि किसी ऑब्जेक्ट पर जासूसी रोकने के लिए मुझे क्या करना है। आपका जवाब बहुत स्पष्ट और सहायक रहा है। और चमेली चट्टानों को स्वचालित रूप से इसके लिए ख्याल रखने के लिए ख्याल रखना। – xverges

94

, की स्थापना isSpyfalse के लिए एक बहुत बुरा विचार है, क्योंकि तब आप एक जासूस पर जासूसी और जब जैस्मीन अपनी कल्पना के अंत में जासूसों को साफ करता है आप मूल विधि नहीं मिलेगा । विधि पहले जासूस के बराबर होगी।

यदि पहले से ही किसी विधि पर जासूसी कर रहे हैं और आप मूल विधि को कॉल करना चाहते हैं तो आपको andCallThrough() पर कॉल करना चाहिए जो पहले जासूस व्यवहार को ओवरराइड करेगा।

उदाहरण

var spyObj = spyOn(obj,'methodName').andReturn(true); 
spyObj.andCallThrough(); 

आप this.removeAllSpies() (this - कल्पना) को फोन करके सब जासूस साफ कर सकते हैं के लिए

+0

धन्यवाद, यह काम करता है! – dbrin

+0

यह इमो है सबसे अच्छा समाधान है। –

+0

मैं यह कहना पसंद करता हूं कि गलत करने के लिए isSpy सेटिंग करना एक बुरी चीज है। मुझे एंड्रियास के बाहर सोचने वाले बॉक्स से बाहर पसंद है। – KSev

8

जैस्मीन 2 में, जासूस राज्य एक SpyStrategy उदाहरण में आयोजित किया जाता है। आप इस उदाहरण को $.ajax.and पर कॉल कर सकते हैं। the Jasmine source code on GitHub देखें।

तो, एक अलग नकली विधि सेट करने के लिए ऐसा करते हैं:

$.ajax.and.callFake(function() { ... }); 

मूल विधि को रीसेट करने के लिए ऐसा करते हैं:

$.ajax.and.callThrough(); 
+1

मुझे नहीं लगता कि '$ .ajax.and.andCallThrough();' सही है । '$ .ajax.and.callThrough();' – kriskodzi

+0

होना चाहिए जो मेरे लिए काम करता है; 'पहले से पहले' के अंदर: 'spyOn (Foobar,' getFoo ')। और .returnValue (' जेनेरिक '); } 'फिर' '' के अंदर: 'Foobar.getFoo.and.returnValue (' special ') '। धन्यवाद! –

0

या आप यह

describe('test', function() { 
 
    var a, c; 
 
    c = 'spy1'; 
 
    a = { 
 
     b: function(){} 
 
    }; 
 

 
    beforeEach(function() { 
 
     spyOn(a, 'b').and.callFake(function() { 
 
      return c; 
 
     }); 
 
    }) 
 

 
    it('should return spy1', function() { 
 
     expect(a.b()).toEqual('spy1'); 
 
    }) 
 

 
    it('should return spy2', function() { 
 
     c = 'spy2'; 
 
     expect(a.b()).toEqual('spy2'); 
 
    }) 
 

 
})
कर सकते हैं

इस मामले में आप एक ही जासूस का उपयोग करते हैं, लेकिन यह बदले में बदल जाएगा कि वे वापस आ जाएंगे ..

3

यह जैस्मीन 2.5 में मेरे लिए काम करता है ताकि नकली AJAX की पुन: सेटिंग की अनुमति मिल सके।

function spyOnAjax(mockResult) { 
    // must set to true to allow multiple calls to spyOn: 
    jasmine.getEnv().allowRespy(true); 

    spyOn($, 'ajax').and.callFake(function() { 
     var deferred = $.Deferred(); 
     deferred.resolve(mockResult); 
     return deferred.promise(); 
    }); 
} 

तो फिर तुम यह त्रुटि के बिना कई बार फोन कर सकते हैं। spyOnAjax (mock1); spyOnAjax (mock2);

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

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