2011-03-17 16 views
53

में JQuery चयनकर्ताओं पर जासूसी मैं जैस्मीन के साथ कुछ जावास्क्रिप्ट का परीक्षण कर रहा हूं और एक jQuery चयनकर्ता द्वारा उपयोग किए जाने वाले डोम के तत्व (जाक) पर जासूसी करना चाहता हूं।जैस्मीन

मेरे कल्पना है:

it("should be able to mock DOM call", function() { 

    spyOn($("#Something"), 'val').andReturn("bar"); 

    result = $("#Something").val(); 

    expect(result).toEqual("bar"); 

}); 

मेरी specrunner.html में मेरे पास है:

उम्मीद डोम कॉल उपहास करने के लिए सक्षम होना चाहिए:

<input type="hidden" id="Something" value="foo" /> 

दुर्भाग्य से कल्पना के साथ विफल बराबर 'बार' के लिए 'foo'।

उत्तर

86

इस लाइन गलत है:

spyOn($("#Something"), 'val').andReturn("bar"); 

चमेली के spyOn समारोह दो पैरामीटर की उम्मीद है। पहला एक मौजूदा वस्तु है। दूसरा स्ट्रिंग के रूप में एक फ़ंक्शन नाम है। आप फ़ंक्शन नाम में स्ट्रिंग ("वैल") के रूप में सही ढंग से गुजर रहे हैं लेकिन आप किसी मौजूदा ऑब्जेक्ट में पहले पैरामीटर के रूप में नहीं जा रहे हैं।

$("#Something") 

... एक मौजूदा वस्तु नहीं है। यह एक jQuery चयनकर्ता का परिणाम (वापसी मूल्य) है। अधिक विशेष रूप से, यह एक jQuery ऑब्जेक्ट को मिलान किए गए नोड्स का प्रतिनिधित्व करेगा - परिणाम की एक सरणी की तरह।

$ 

... एक मौजूदा वस्तु है।

$.fn 

... एक मौजूदा वस्तु है।

$("#Something") 

... नहीं किसी मौजूदा ऑब्जेक्ट है - यह है एक jQuery चयनकर्ता का परिणाम है।

यह काम करेगा:

it("should be able to mock DOM call", function() { 
    //spyOn($.fn, "val").andReturn("bar"); //pre-jasmine 2.0 syntax 
    spyOn($.fn, "val").and.returnValue("bar"); //Jasmine 2.0 Syntax 
    var result = $("#Something").val(); 
    expect(result).toEqual("bar"); 
}); 
+4

मैं भी उलझन में हूं। 'var $ foo = $ ('# foo')'। अब '$ foo' एक मौजूदा ऑब्जेक्ट है: यह एक jQuery ऑब्जेक्ट है। इसमें 'वैल()' विधि है; यह सिर्फ अपनी प्रोटोटाइप श्रृंखला को 'jQuery.fn' पर देखकर प्राप्त होता है। तो मैं 'spyOn ($ foo," val ") क्यों नहीं कर सकता? जैस्मीन के जासूसी को मुझे यह निर्दिष्ट करने की आवश्यकता क्यों है कि विधि कहां परिभाषित की गई है? मेरा उपयोग मामला यह है कि मैं इसे देखना चाहता हूं, कहें, 'छुपाएं() 'सामान्य रूप से नहीं, बल्कि ** $ foo ** पर कॉल किया गया है। तो 'spyOn (jQuery.fn, "hide")' मुझे वह जानकारी नहीं देता जो मैं चाहता हूं, लेकिन 'spyOn ($ foo, "hide")' होगा - अगर यह काम करता है। –

+0

@NathanLong सही है - यह गलत जवाब है। मुझे यकीन नहीं है कि इसे इतना ऊंचा क्यों किया गया है .. – badunk

+13

@NathanLong समस्या यह है कि हर बार जब आप एक jquery चयनकर्ता निष्पादित करते हैं, तो आपको एक नया ऑब्जेक्ट मिलता है, इसलिए जिस पर आप जासूसी करने के लिए सेट अप करते हैं, उससे अलग होना परीक्षण के तहत कोड के अंदर आपको मिलता है। इसलिए एलेक्स आपको सभी jquery वस्तुओं के लिए प्रोटोटाइप ($ .fn) जासूसी करने के लिए कह रहा है। –

16

समस्या यह है कि दो कॉल दो अलग-अलग jQuery-wrapped नोड्स लौटाते हैं।

यह काम करना चाहिए: [email protected]:

it("should be able to mock DOM call", function(){ 

    // var node = $("Something"); 
    // spyOn(node, 'val').andReturn('bar'); 

    // expect(node.val()).toEqual('bar'); 
    var node = $("Something"); 
    spyOn(node, 'val').and.returnValue('bar'); 

    expect(node.val()).toEqual('bar'); 
}); 

अगली बार, मदद जैस्मीन मेलिंग सूची के बारे में अधिक प्रचलित है।

+6

यह आपका उत्तर है, jQuery प्रत्येक क्वेरी के लिए एक अलग वस्तु देता है, भले ही यह वही चयनकर्ता हो। इसे ठीक से जासूसी करने के लिए आपको उसी ऑब्जेक्ट को संदर्भित करने की आवश्यकता है। अन्यथा, आप एक पर जासूसी कर रहे हैं, और दूसरे पर निष्पादित कर रहे हैं। – badunk

+1

इस उम्मीद की कोशिश करें: उम्मीद करें (नोड.वल) .toHaveBeenCalled() –

27

लगता है जैसे मैं अच्छा समाधान

it "should open past statuses", -> 
     # We can't use $('.past') here cause each time $('.past') called it returns different objects 
     # so we need to store spy in variable 
     showSpy = spyOn($.fn, 'show') 
     # do the stuff 
     $('.show-past').click() 
     # then check if 'show' action was called 
     expect($.fn.show).toHaveBeenCalled() 
     # and if it realy our object 
     expect(showSpy.mostRecentCall.object.selector).toEqual('.past') 

यह आपके कोड पर आधारित नहीं है पाया, लेकिन मैं इस किसी की मदद कर सकते हैं उम्मीद है। और, हाँ, उदाहरण कॉफ़ीस्क्रिप्ट में।

+2

। चयनकर्ता को jQuery 1.7+ में बहिष्कृत किया गया है। 1.7+ संस्करणों में इसके लिए वैकल्पिक क्या है? – Venugopal

2

मैंने एक सहायक-कार्य लिखा, जो आईडी/मूल्य-जोड़ों की एक सरणी स्वीकार करता है। समारोह आईडी-चयनकर्ता के साथ कहा जाता है -

var jasminTestHelper = { 
    spyOnValAndFake : function(obj) { 
     var i, j; 
     spyOn($.fn, 'val').andCallFake(function() { 
      for (i = 0, j = obj.length; i < j; i++) { 
       if (this.selector === '#' + obj[i][0]) { 
        return obj[i][1]; 
       } 
      } 
     }) 
    } 
} 

प्रत्येक जोड़ी जो आईडी, jQuery-वैल() करता है, तो जो मान दिया जाना चाहिए के लिए ठग-समारोह में बताता है।यह इस तरह से प्रयोग किया जाता है:

jasminTestHelper.spyOnValAndFake([["id1", "value1"], ["id2", "value2"]]); 

तो $('#id1').val() परीक्षण के तहत अपने समारोह में कहा जाता है, नकली-फ़ंक्शन value1, $('#id2').val() कहा जाता है अगर यह रिटर्न value2। तो आपको डोम के साथ परेशान करने की आवश्यकता नहीं है, आप बस jQuery-val() - फ़ंक्शन का मज़ाक उड़ाते हैं और वापसी-मूल्यों का अनुकरण करते हैं। अन्य jQuery-फ़ंक्शंस शायद उसी तरह से मजाक कर सकते हैं।

+0

मैं इस पेड़ को '$ (चयनकर्ता) 'कॉल के लिए भौंक रहा हूं। फिलहाल मैं कई चयनकर्ताओं को एक बार में मजाक करने के लिए कुश्ती बनाने के साथ कुश्ती कर रहा हूं, लेकिन अब मुझे जो मिला है वह https://github.com/alxndr/sundries/blob/master/spy-on- jQuery-helper.js – alxndr

2

आप अपनी खुद की नकली डोम तत्व बनाने और उसके बाद $ ('# elementid') इस्तेमाल कर सकते हैं [0] सामान्य

addFakeElementWithId = function (elementId) { 
     var fake = document.createElement("div"); 
     fake.setAttribute("id", elementId); 
     document.body.appendChild(fake); 
    }; 
1

मुझे लगता है कि मेरी चमेली संस्करण में बदलाव (2.0.3) के रूप में होती है, इसलिए एलेक्स यॉर्क द्वारा समाधान काम नहीं किया, लेकिन निश्चित रूप से मुझे एक रास्ता दिया। तो यहाँ काम कर रहे कल्पना jQuery कोड है जो

$('someSelector').data('someAttribute').enable(); 

यहाँ परीक्षण किया जाना है

var mockJqueryObject = { enable:function(){},disable:function(){}}; 
//this mocks the .data('someAttribute') in above code. 
spyOn($.fn, "data").and.returnValue(mockSelectBoxObject); 

एक और सुव्यवस्थित कल्पना

के रूप में नकली का एक और स्तर इस्तेमाल कर सकते हैं इसके बारे में चमेली कल्पना हिस्सा है
spyOn(mockJqueryObject,"enable") 
spyOn(mockJqueryObject,"disable") 
संबंधित मुद्दे