2012-08-22 17 views
28

का उपयोग करके किए गए और असफल डिफरर्ड ऑब्जेक्ट का परीक्षण कैसे करें जावास्क्रिप्ट सबमिट अनुरोध (1) के बारे में कोड यहां दिया गया है।
यहां जैस्मीन (2) का उपयोग करके AJAX अनुरोध को मजाक करने के बारे में परीक्षण है।जैस्मीन

मैं सर्वर व्यवहार का नकल करना चाहता हूं। कोई विचार?
अधिक जानकारी के लिए (1) और (2) में टिप्पणी देखें।

पीएस .:
असल में दोनों मामलों में नकली फंक्शन के विफल और असफल डिफरर्ड ऑब्जेक्ट को बुलाया जाता है।


(1)

submitForm: function() { 
    // the server execute fail only if message.val() is empty 
    // and I would like to mock this behaviour in (2) 
    backendController.submitForm(message.val()).done(this.onSuccess).fail(this.onError); 
}, 

backendController.submitForm = function (message) { 
    return $.ajax({ 
     url: 'some url', 
     type: 'POST', 
     dataType: 'json', 
     data: { 
      message: message 
     } 
    }).done(function() { 
     //some code; 
    }); 
}; 

(2)

describe('When Submit button handler fired', function() { 
    var submitFormSpy, 
     fakeFunction = function() { 
      this.done = function() { 
       return this; 
      }; 
      this.fail = function() { 
       return this; 
      }; 
      return this; 
     }; 

    beforeEach(function() { 
     submitFormSpy = spyOn(backendController, 'submitForm').andCallFake(fakeFunction); 
    }); 

    describe('if the message is empty', function() { 
     beforeEach(function() { 
      this.view.$el.find('#message').text(''); 
      this.view.$el.find('form').submit(); 
     }); 
     it('backendController.submitForm and fail Deferred Object should be called', function() { 
      expect(submitFormSpy).toHaveBeenCalled(); 
      // how should I test that fail Deferred Object is called? 
     }); 
    }); 

    describe('if the message is not empty', function() { 
     beforeEach(function() { 
      this.view.$el.find('#message').text('some text'); 
      this.view.$el.find('form').submit(); 
     }); 
     it('backendController.submitForm should be called and the fail Deferred Object should be not called', function() { 
      expect(submitFormSpy).toHaveBeenCalled(); 
      // how should I test that fail Deferred Object is not called? 
     }); 
    }); 

}); 
+0

में किया() कोड अपने अजाक्स के चारों ओर एक आवरण का उपयोग करके कॉल उन्हें बहुत आसान परीक्षण करना होगा। Https://github.com/webadvanced/takeCommand – Paul

+1

@Paul अपने सुझाव के लिए धन्यवाद देखें। असल में मुझे समझ में नहीं आ रहा है कि मुझे '/ webadvanced/takeCommand' का उपयोग क्यों करना चाहिए क्योंकि $ .ajax' के पास पहले से ही मुझे चाहिए। क्या आप मुझे कुछ उदाहरण कोड लिखने का उत्तर दे सकते हैं? –

+0

var spy = spyOn (कक्षा, "विधि"); actionThatCallsClassMethod(); उम्मीद (जासूसी) .toHaveBeenCalled(); ने मुझे आपके उदाहरण से बाहर करने में मदद की। – Aligned

उत्तर

24

हम वास्तव में, एक ही समस्या में पड़ गए स्थगित वस्तुओं है कि ऑन-द-मक्खी templating के लिए टेम्पलेट स्क्रिप्ट Ajaxed का प्रतिनिधित्व करते हैं परीक्षण करने के लिए कोशिश कर रहा। हमारे परीक्षण समाधान में जैस्मीन के संयोजन के साथ Jasmine-Ajax लाइब्रेरी का उपयोग करना शामिल है।

तो शायद यह कुछ इस तरह होगा:

describe('When Submit button handler fired', function() { 
    jasmine.Ajax.useMock(); 

    describe('if the message is empty', function() { 

    beforeEach(function() { 
     spyOn(backendController, 'submitForm').andCallThrough(); 
     // replace with wherever your callbacks are defined 
     spyOn(this, 'onSuccess'); 
     spyOn(this, 'onFailure'); 
     this.view.$el.find('#message').text(''); 
     this.view.$el.find('form').submit(); 
    }); 

    it('backendController.submitForm and fail Deferred Object should be called', function() { 
     expect(backendController.submitForm).toHaveBeenCalledWith(''); 
     mostRecentAjaxRequest().response({ 
     status: 500, // or whatever response code you want 
     responseText: '' 
     }); 

     expect(this.onSuccess).not.toHaveBeenCalled(); 
     expect(this.onFailure).toHaveBeenCalled(); 
    }); 
}); 

एक और बात, अगर आप हैं, ताकि आप में पूरे डोम करने वाली प्रतिक्रिया-कॉलबैक पथ का परीक्षण नहीं करते कार्यक्षमता को तोड़ने के लिए कोशिश कर सकते हैं एक परीक्षण यदि आप पर्याप्त रूप से दानेदार हैं, तो आप वास्तव में अपने परीक्षणों के भीतर डिफरर्ड ऑब्जेक्ट्स का उपयोग कर एसिंक्रोनस डिफरर्ड रेज़ोल्यूशन का परीक्षण कर सकते हैं!

कुंजी वास्तव में अपने परीक्षणों में डिफरर्ड ऑब्जेक्ट्स का उपयोग करना है, ताकि expect कॉल का दायरा अभी भी आपके it फ़ंक्शन ब्लॉक में हो।

describe('loadTemplate', function() { 
    it('passes back the response text', function() { 
    jasmine.Ajax.mock(); 
    loadTemplate('template-request').done(function(response) { 
     expect(response).toBe('foobar'); 
    }); 
    mostRecentAjaxRequest().response({ status:200, responseText:'foobar' }); 
    }); 
}); 
+0

यह निश्चित रूप से लेने का दृष्टिकोण है - यह जानना अच्छा है कि जैस्मीन ने इसे बनाया है, लेकिन यदि आप कुनिट या अन्य यूनिट परीक्षण ढांचे का उपयोग कर रहे हैं - [sinon.js] (http://sinonjs.org/) में सब कुछ है इन स्टब्स/fakeXHR आदि भी। – gnarf

+0

ध्यान दें कि जैस्मीन-एजेक्स 3.0 'प्रतिक्रिया' के अनुसार' प्रतिक्रिया 'के साथ प्रतिस्थापित किया गया है, [रिलीज नोट्स] देखें (https://github.com/jasmine/jasmine-ajax/blob/master/release_notes/3.0.md) – ivarni

3

यह बहुत अगर आप ajax अनुरोध वादा वस्तु के साथ एक वर था परीक्षण करने के लिए आसान होगा। उस स्थिति में आप कर सकते हैं:

it('should do an async thing', function() {  
    var mutex = 1; 
    var promF = jasmine.createSpy('prF'); 

    runs(function() { 
    var promise1 = $.ajax(); 
    promise1.always(function(){ 
     mutex--; 
    }); 
    promise1.fail(function(){ 
     promF(); 
    }); 
    }); 

    waitsFor(function(){ 
    return !mutex; 
    }, 'Fetch should end', 10000); 

    runs(function() { 
     expect(promF).toHaveBeenCalled(); 
    }); 
}); 

नीचे मैं अनचाहे कोड पोस्ट करता हूं जो आपके अनुरूप हो सकता है। मुझे लगता है कि AJAX कॉल .submit() कक्षा से शुरू किया गया है? हो सकता है कि आपको एजेक्स अनुरोध को रन() ब्लॉक से प्रारंभ करना चाहिए और पहले से() से नहीं, लेकिन आपको यह सुनिश्चित करना चाहिए कि कौन सा काम करता है।

describe('When Submit button handler fired and city is defined', function() { 
    var ajaxRequestSpy, 
     failSpy, successSpy, alwaysSpy, 
     mutex; 
    beforeEach(function() { 
     ajaxRequestSpy = spyOn(backendController, 'ajaxRequest').andCallThrough(); 
     failSpy = spyOn(ajaxRequestSpy(), 'fail').andCallThrough() 
     successSpy = spyOn(ajaxRequestSpy(), 'success').andCallThrough(); 
     mutex = 1; // num of expected ajax queries 
     alwaysSpy = spyOn(ajaxRequestSpy(), 'always').andCallFake(function() { 
      mutex--; 
     }); 
     this.view = new MyView({ 
      el: $('<div><form>' + 
       '<input type="submit" value="Submit" />' + 
       '<input type="text" name="city">' + 
       '</form></div>') 
     }); 
     this.view.$el.find('form').submit(); 
    }); 
    it('backendController.ajaxRequest should be called', function() { 
     runs(function() { 
      // maybe init ajax here ? 
     }); 

     waitsFor(function() { 
      return !mutex; 
     }, 'ajax request should happen', 5000); 

     runs(function() { 
      expect(ajaxRequestSpy).toHaveBeenCalled(); // true 
      expect(failSpy).toHaveBeenCalled(); // Error: Expected spy fail 
              // to have been called. 
     }); 

    }); 
}); 

लेकिन, मुझे यकीन है कि लाइन

failSpy = spyOn(ajaxRequestSpy(), 'fail').andCallThrough(); 

आप क्या चाहते हैं करता है कि नहीं कर रहा हूँ। क्या किसी अन्य जासूसी पर जासूसी करना संभव है? और यदि हां, तो आप जासूस क्यों बुला रहे हैं? हो सकता है आप की कोशिश करनी चाहिए

failSpy = spyOn(ajaxRequestSpy, 'fail').andCallThrough(); 
13

यहां बताया गया है कि मैं इसे कैसे करने में कामयाब रहा।

अनिवार्य रूप से, $ .ajax ऑब्जेक्ट एक डिफरर्ड ऑब्जेक्ट देता है, ताकि आप $ .ajax पर जासूसी कर सकें और एक डिफरर्ड वापस कर सकें और फिर इसे चलाने के लिए मैन्युअल रूप से ट्रिगर कर सकें।आपकी जावास्क्रिप्ट

कोड

Index.prototype.sendPositions = function() { 
    var me = this; 
    $.ajax({ 
    ... 
    }).done(function(data, textStatus, jqXHR) { 
    me.reload(); 
    }).fail(function(jqXHR, textStatus, errorThrown) { 
    console.log(errorThrown); 
    }); 
}; 

टेस्ट

it("should reload the page after a successful ajax call", function(){ 
    var deferred = new jQuery.Deferred(); 
    spyOn($, 'ajax').andReturn(deferred); 
    spyOn(indexPage, 'reload'); 
    indexPage.sendPositions(); 
    deferred.resolve('test'); 
    expect(indexPage.reload).toHaveBeenCalled(); 
}); 
+2

असफल पर जासूसी करने के लिए पीएस, deferred.resolve() कॉल deferred.reject() – Tony

+0

कॉल करने के बजाय बहुत आसान, धन्यवाद! – dbrin

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

  • कोई संबंधित समस्या नहीं^_^