2012-02-28 16 views
6

मैं एक बहुत ही कठिन समय कैसे एक वस्तु है कि मुझे मेरे jQuery कॉल का परीक्षण करके पता सेटअप करने के लिए समझने आ रही हैं परीक्षण करने के लिए। मुझे किसी भी Async कॉल या कुछ भी नकल करने की आवश्यकता नहीं है, केवल मूल उपयोग। तो मुझे मेरे समारोह मैं परीक्षण करना चाहते हैं निर्धारित करते हैं (सादगी के लिए छोटा कर दिया):jQuery मजाक बुनियादी उपयोग

listGamesCallback : function(data) { 
    var gameList = $("#gameList select"); 

    gameList.empty(); 

    $.each(data, function() { 
      var newOption = $('<option>', {value : this.gameId }); 
      newOption.text(string); 
      newOption.data("isJoinable", isJoinable); 

      // Add it to the list 
      gameList.append(newOption); 
    }); 


} 

मैं इकाई परीक्षण इस विधि करने के लिए यहाँ jQuery नकली करने की जरूरत है, लेकिन मैं ऐसा करने के तरीके यह पता लगाने में असमर्थ हूँ जावास्क्रिप्ट में। jsMockito बिना भी, मैं गुण jQuery इस स्थिति में है कि के साथ एक वस्तु बनाने के लिए कैसे पता नहीं है। इससे संबन्धित किसी भी मदद का स्वागत किया जाएगा।

मैं jsTestDriver, jsHamcrest, jsMockito और jQuery का उपयोग कर रहा हूं। हालांकि एक $ ऑब्जेक्ट बनाने के लिए एक सामान्यीकृत दृष्टिकोण जिसमें इन गुणों का भी शानदार होगा। धन्यवाद!

उन लोगों के लिए, जो मैंने पूछा था, यहां थोड़ी सी काम लग रही थी..लेकिन मुझे समझ में नहीं आता क्यों।

var saved$ = $; 

var mockContruct = mockFunction(); 
var mockedGamelist = mock(jQuery); 
var mockedOption = mock(jQuery); 

mocked$ = (function() { 
    var test = function(name) { 
     var args = jQuery.makeArray(arguments); 
     return mockContruct.call(test, args); 
    }; 

    $.extend(test, $); 

    // This is what confuses me. This worked, but it's wierd 
    // It allows me to use the regular jQuery functions like 
    // $.each, while returning mocked objects when selectors are used. 
    test.prototype.constructor = test; 

    return test; 
})(); 

$ = mocked$;  

when(mockContruct).call(anything(), hasItem(containsString("#gameList"))) 
    .thenReturn(mockedGamelist); 

when(mockContruct).call(anything(), hasItems(containsString("<option>"), both(object()).and(hasMember("value")))) 
     .thenReturn(mockedOption); 

headerFunctions.listGamesCallback([ { 
    gameId : 1, 
    isWhitesTurn : false, 
    isGameOver : false, 
    whiteUserName : "foobar", 
    blackUserName : "barfoo" 
} ]); 

JsMockito.verify(mockedGamelist).empty(); 
JsMockito.verify(mockedGamelist).append(mockedOption); 

$ = saved$; 
+0

यदि आप अपना टेस्ट कोड भी प्रदान करते हैं तो यह उपयोगी होगा। :) – alpian

+0

ठीक है, देर से उत्तर के लिए खेद है, लेकिन मुझे फिर से सौंप दिया गया है इसलिए इसे कम प्राथमिकता मिली। मुझे उस प्रश्न को चलाने के लिए एक ठोस तरीका मिला है जिसे मैंने प्रश्न में संपादित किया था। यह बहुत अच्छी तरह से लिखा नहीं गया है क्योंकि मुझे समझ में नहीं आता कि jQuery यह करता है कि यह कैसे करता है। – CrazyBS

+0

आपके द्वारा लिखे गए परीक्षण वास्तव में आपके कोड निष्पादन के अलावा कुछ भी साबित नहीं करते हैं। यह समस्याओं के साथ अन्य परीक्षणों को भी प्रदूषित कर सकता है यदि यह विफल रहता है क्योंकि यदि विफल हो जाता है तो आप $ को पुनर्स्थापित नहीं करेंगे। मुझे लगता है कि आप अभी भी इन परीक्षणों के बिंदु को खो रहे हैं: आपको ** व्यवहार ** के लिए एक परीक्षा लिखनी चाहिए ** आप अपने कोड से उम्मीद कर रहे हैं, न कि यह कैसे करता है इसका विवरण नहीं। आपको एक ऐसा परीक्षण लिखने की कोशिश करनी चाहिए जो सिर्फ यह सुनिश्चित करने पर केंद्रित हो कि उस गेमलिस्ट में एक्स विकल्प हैं जो आपके फ़ंक्शन चलाने के बाद उनमें से किसी भी मूल्य के साथ है। – alpian

उत्तर

1

ठीक है, यहां मैं जो कुछ आया उसके साथ न्यूनतम सेटअप के साथ काम करता है। .extend यहां पूरी तरह से जरूरी है ताकि jQuery ऑब्जेक्ट सही ढंग से सेटअप हो। यह आपको मज़ाक उड़ाया jQuery वस्तुओं है कि तुम पर अपने परीक्षण चलाने के लिए उपयोग कर सकते हैं वापस जाने के लिए निर्माता उपहास करने के लिए अनुमति देता है। एक जासूस के रूप में, jQuery सभी स्थितियों में अपेक्षित के रूप में काम करेगा, सिवाय इसके कि जब आप इसे कुछ और करना चाहते हैं। यहां यह है:

TestCase("HeaderTest", { 
    testListGamesCallback : function() { 
     var saved$ = $; 

     $ = $.prototype.construct = jQuery.extend(spy(jQuery), jQuery); 

     var mockGameList = mock(jQuery); 
     when($)(containsString("#gameList")).thenReturn(mockGameList); 

     headerFunctions.listGamesCallback([ { 
      gameId : 1, 
      isWhitesTurn : false, 
      isGameOver : false, 
      whiteUserName : "foobar", 
      blackUserName : "barfoo" 
     } ]); 

     verify(mockGameList).empty(); 
     verify(mockGameList).append(object()); 

     $ = saved$; 
    } 
}); 

इस समाधान के लिए चेतावनी यह है कि कन्स्ट्रक्टर के अलावा कुछ भी मजाक करना थोड़ा मुश्किल है। आपको प्रत्येक व्यक्तिगत फ़ंक्शन को सेट करना होगा जिसे आप नकल करना चाहते हैं, फिर व्यवहार को प्रोग्राम करें। तो:

$.each = mockFunction(); 
when($.each)(...matchers...).thenReturn(...); 

लेकिन यह अभी भी परीक्षण क्या आप की जरूरत है के लिए अनुमति देता है।

0

नहीं यकीन है कि अगर मैं समझता हूँ तुम क्या मतलब है, लेकिन आप आप उदाहरण के लिए 'डेटा' बनाना चाहते हैं, इस विधि मुझे पता है:

var data = [ { id : 1 , name : 'foo' } , { id : 2, name : 'bar' ] ​ 

लेकिन - यदि आप एक बनाना चाहता था विकल्पों की सूची है, तो आप कोड से फिक्स की एक जोड़ी की जरूरत है: मजाक jQuery क्या मजाक के लिए है नहीं है को देखने के http://jsfiddle.net/7MMap/

var data = [ { gameId : 1 , name : 'foo' ,isJoinable:true} , { gameId : 2, name : 'bar' ,isJoinable:false}] 

    listGamesCallback = function(data) { 
    var gameList = $("#gameList select") 
        .empty(); 

    $.each(data, function(i,d) { 
      var newOption = $('<option>', {value : d.gameId }) 
      .text(d.name) 
      .data("isJoinable", d.isJoinable); 

      // Add it to the list 
      gameList.append(newOption); 
    }) 
      }; 

listGamesCallback(data); 
+0

असल में, jQuery.each() फ़ंक्शन आपको 'इस' के साथ सीधे मूल्य तक पहुंचने की अनुमति देता है। और वे सभी .text() डेटा() मॉकिंग और आईएमएचओ को जटिल बनाता है, यह इसे कम पठनीय बनाता है। लेकिन यह सिर्फ राय है। आपके अच्छी तरह से स्वरूपित उत्तर के लिए धन्यवाद। मैं अभी भी jQuery को नकली करने के लिए देख रहा हूँ। – CrazyBS

0

। आप केवल कभी अपने वस्तु की सहयोगियों मजाक किया जाना चाहिए। jQuery कुछ उपयोगिताओं के साथ आप प्रदान कर रहा है - यह एक सहयोगी नहीं है और इसलिए मज़ाक उड़ाया नहीं किया जाना चाहिए।

आप यहां क्या सहयोग कर रहे हैं डीओएम, या आपके कोड और डोम के बीच कुछ मध्यवर्ती वस्तु है। data एक मूल्य वस्तु है और के रूप में एवी पता चलता है बस अपने परीक्षण में बनाया जा सकता है।

मेरे जेएस परीक्षणों में, मैं डोम का नकल नहीं करता हूं, मैं असली डोम का उपयोग करता हूं और परीक्षण के बीच मैंने जो कुछ भी बनाया है उसे फाड़ना सुनिश्चित करता हूं और ऐसा लगता है कि यह बहुत अच्छी तरह से काम करता है।

+0

मैं इस स्थिति में अपने परीक्षण के बारे में सहमत हूं। हालांकि, मेरी सोच यह थी कि चूंकि मैं जितना संभव हो सके अपना परीक्षण चाहता हूं, मैं नहीं चाहता कि jQuery वास्तव में कुछ भी करे, मुझे बस यह सत्यापित करने की आवश्यकता है कि इसका उपयोग किया गया था। हालांकि यह आवश्यक है कि परीक्षण हमेशा पास करने के लिए jQuery का उपयोग किया जाए। तो आपके पास एक बिंदु है। – CrazyBS

+0

क्या मैं डोम का नकल कर सकता हूं ?! – CrazyBS

+0

बेशक आप ** ** ** कर सकते हैं, लेकिन आपके मामले में मैं वास्तव में, बस अपने परीक्षण में, वास्तविक गेम में आईडी गेमलिस्ट के साथ एक वास्तविक चयन जोड़ें, और उसके बाद अपना फ़ंक्शन चलाएं, और फिर इसे चलाने के बाद साबित करें (कहें सीएसएस चयनकर्ताओं के साथ) कि डोम जिस तरह से दिखता है उसे देखता है - फिर उस चयन को हटाकर अपने आप को साफ करें। JQuery को नकल करने की कोशिश करने के बारे में भूल जाओ - यह एक उपयोगिता है - और आपको ऐसा करने की आवश्यकता नहीं है :)। – alpian

1

अल्पायन के उत्तर के विस्तार के रूप में, आप पृष्ठ पर उन्हें जोड़ने के बिना डोम तत्व बना सकते हैं।

listGamesCallback : function(data, gameListSelectElem) { 
    var gameList = $(gameListSelectElem); 
    ... 

और उन्हें इतनी तरह का परीक्षण: अपने जे एस कार्यों पैरामीटर के रूप में प्रासंगिक तत्वों ले बनाओ

var fakeSelect = $('<select>'), 
    data = ...; 

listGamesCallback(data, fakeSelect[0]); 

equal(fakeSelect.find('option').length, 1, 'must have exactly 1 option'); 
... 

कोड की अंतिम पंक्ति ऊपर qUnit के लिए है। जो कुछ भी आपको चाहिए उसे ले लो, बिंदु यह कहना है कि आप एक डोम तत्व को पारित कर सकते हैं जिसे पृष्ठ में कभी नहीं जोड़ा गया था और बाद में यह जांचने के लिए कि डीओएम तत्व का उपयोग करके डीओएम तत्व की जांच करें कि यह सही तरीके से छेड़छाड़ की गई है या नहीं।

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