मैं जैस्मीन के साथ jQuery AJAX घटनाओं को कैसे सत्यापित करूं?


114

मैं बुनियादी jQuery AJAX अनुरोधों के लिए कुछ BDD चश्मा लिखने के लिए जैस्मीन का उपयोग करने की कोशिश कर रहा हूं। मैं वर्तमान में स्टैंडअलोन मोड (यानी के माध्यम से SpecRunner.html) में जैस्मीन का उपयोग कर रहा हूं । मैंने jquery और अन्य .js फ़ाइलों को लोड करने के लिए SpecRunner कॉन्फ़िगर किया है। किसी भी विचार क्यों निम्नलिखित काम नहीं करता है? has_returned सत्य नहीं हुआ, यहाँ तक कि "युप्पी" भी सोचा! चेतावनी ठीक दिखाता है।

describe("A jQuery ajax request should be able to fetch...", function() {

  it("an XML file from the filesystem", function() {
    $.ajax_get_xml_request = { has_returned : false };  
    // initiating the AJAX request
    $.ajax({ type: "GET", url: "addressbook_files/addressbookxml.xml", dataType: "xml",
             success: function(xml) { alert("yuppi!"); $.ajax_get_xml_request.has_returned = true; } }); 
    // waiting for has_returned to become true (timeout: 3s)
    waitsFor(function() { $.ajax_get_xml_request.has_returned; }, "the JQuery AJAX GET to return", 3000);
    // TODO: other tests might check size of XML file, whether it is valid XML
    expect($.ajax_get_xml_request.has_returned).toEqual(true);
  }); 

});

मैं कैसे परीक्षण करूं कि कॉलबैक कहा गया है? जैस्मीन के साथ async jQuery के परीक्षण से संबंधित ब्लॉग / सामग्री के लिए कोई संकेत बहुत सराहना की जाएगी।

जवाबों:


234

मुझे लगता है कि आप दो प्रकार के परीक्षण कर सकते हैं:

  1. AJAX अनुरोध (जैस्मीन के जासूसों का उपयोग करके) को नकली बनाने वाली इकाई परीक्षण, आपको AJAX अनुरोध के ठीक पहले और बाद में चलने वाले अपने सभी कोड का परीक्षण करने में सक्षम बनाता है । तुम भी सर्वर से एक प्रतिक्रिया नकली नकली जैस्मीन का उपयोग कर सकते हैं। ये परीक्षण तेज़ होंगे - और उन्हें अतुल्यकालिक व्यवहार को संभालने की आवश्यकता नहीं होगी - क्योंकि कोई वास्तविक AJAX नहीं चल रहा है।
  2. एकीकरण परीक्षण जो वास्तविक AJAX अनुरोध करते हैं। इन्हें अतुल्यकालिक होने की आवश्यकता होगी।

जैस्मीन आपको दोनों तरह के टेस्ट करने में मदद कर सकती है।

यहाँ एक नमूना है कि आप AJAX अनुरोध को कैसे नकली कर सकते हैं, और फिर यह सत्यापित करने के लिए एक इकाई परीक्षण लिखें कि नकली AJAX अनुरोध सही URL पर जा रहा है:

it("should make an AJAX request to the correct URL", function() {
    spyOn($, "ajax");
    getProduct(123);
    expect($.ajax.mostRecentCall.args[0]["url"]).toEqual("/products/123");
});

function getProduct(id) {
    $.ajax({
        type: "GET",
        url: "/products/" + id,
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    });
}

इसके बजाय जैस्मीन 2.0 का उपयोग करें:

expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/products/123");

जैसा कि इस उत्तर में नोट किया गया है

यहाँ एक समान इकाई परीक्षण है जो सत्यापित करता है कि आपके कॉलबैक को सफलतापूर्वक पूरा करने के लिए AJAX के अनुरोध पर निष्पादित किया गया था:

it("should execute the callback function on success", function () {
    spyOn($, "ajax").andCallFake(function(options) {
        options.success();
    });
    var callback = jasmine.createSpy();
    getProduct(123, callback);
    expect(callback).toHaveBeenCalled();
});

function getProduct(id, callback) {
    $.ajax({
        type: "GET",
        url: "/products/" + id,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: callback
    });
}

इसके बजाय जैस्मीन 2.0 का उपयोग करें:

spyOn($, "ajax").and.callFake(function(options) {

जैसा कि इस उत्तर में नोट किया गया है

अंत में, आपने कहीं और संकेत दिया है कि आप एकीकरण परीक्षणों को लिखना चाहते हैं जो वास्तविक AJAX अनुरोध करते हैं - एकीकरण उद्देश्यों के लिए। यह जैस्मीन की एसिंक्रोनस सुविधाओं का उपयोग करके किया जा सकता है: वेट्स (), वॉट्सफोर () और रन ():

it("should make a real AJAX request", function () {
    var callback = jasmine.createSpy();
    getProduct(123, callback);
    waitsFor(function() {
        return callback.callCount > 0;
    });
    runs(function() {
        expect(callback).toHaveBeenCalled();
    });
});

function getProduct(id, callback) {
    $.ajax({
        type: "GET",
        url: "data.json",
        contentType: "application/json; charset=utf-8"
        dataType: "json",
        success: callback
    });
}

+1 एलेक्स महान जवाब। वास्तव में मुझे इसी तरह के मुद्दे का सामना करना पड़ा, जिसके लिए मैंने एक प्रश्न टेस्ट अजाक्स अनुरोध को आस्थगित ऑब्जेक्ट का उपयोग करके खोला है । क्या आप देख सकते हैं? धन्यवाद।
लोरेन बर्नार्ड

12
मैं वास्तव में चाहता हूं कि आपका जवाब जैस्मीन के लिए आधिकारिक दस्तावेज का हिस्सा था। एक समस्या का बहुत स्पष्ट जवाब जो मुझे कुछ दिनों से मार रहा है।
डेरेन न्यूटन

4
इस उत्तर को वास्तव में इस प्रश्न के आधिकारिक उत्तर के रूप में चिह्नित किया जाना चाहिए।
थॉमस अमर

1
सबसे हाल की कॉल जानकारी प्राप्त करने का मौजूदा तरीका $ .ajax.calls.mostRecent ()
camiblanch

1
सादे जेएस अजाक्स के लिए आप इसे कैसे लागू करेंगे?
चौकीदार

13

: चमेली-ajax परियोजना को देखो http://github.com/pivotal/jasmine-ajax

यह एक ड्रॉप-इन हेल्पर है जो (या तो jQuery या Prototyp.js के लिए) XHR लेयर पर स्टब्स करता है ताकि रिक्वेस्ट कभी आउट न हो। फिर आप अनुरोध के बारे में सभी की अपेक्षा कर सकते हैं।

फिर यह आपको अपने सभी मामलों के लिए स्थिरता प्रतिक्रिया प्रदान करने देता है और फिर प्रत्येक प्रतिक्रिया के लिए परीक्षण लिखता है जो आप चाहते हैं: सफलता, विफलता, अनधिकृत, आदि।

यह अजाक्स को अतुल्यकालिक परीक्षणों के दायरे से बाहर ले जाता है और आपको परीक्षण के लिए बहुत लचीलापन प्रदान करता है कि आपके वास्तविक प्रतिक्रिया हैंडलर कैसे काम करेंगे।


धन्यवाद @jasminebdd, jasmine-ajax प्रोजेक्ट मेरे js कोड के परीक्षण के लिए जाने के तरीके की तरह लग रहा है। लेकिन क्या होगा अगर मैं सर्वर से वास्तविक अनुरोधों के साथ परीक्षण करना चाहता हूं, जैसे कनेक्टिविटी / एकीकरण परीक्षण?
mnacos

2
@mnacos jasmine-ajax ज्यादातर यूनिट टेस्टिंग के लिए उपयोगी है, जिस स्थिति में आप विशेष रूप से सर्वर से कॉल से बचना चाहते हैं। यदि आप एकीकरण परीक्षण कर रहे हैं, तो यह संभवतः वह नहीं है जो आप चाहते हैं और एक अलग परीक्षण रणनीति के रूप में डिज़ाइन किया जाना चाहिए।
सेबस्टियन मार्टिन

7

यहाँ इस तरह एक app js के लिए एक सरल उदाहरण परीक्षण सूट है

var app = {
               fire: function(url, sfn, efn) {
                   $.ajax({
                       url:url,
                       success:sfn,
                       error:efn
                   });
                }
         };

एक नमूना परीक्षण सूट, जो url regexp के आधार पर कॉलबैक कहेगा

describe("ajax calls returns", function() {
 var successFn, errorFn;
 beforeEach(function () {
    successFn = jasmine.createSpy("successFn");
    errorFn = jasmine.createSpy("errorFn");
    jQuery.ajax = spyOn(jQuery, "ajax").andCallFake(
      function (options) {
          if(/.*success.*/.test(options.url)) {
              options.success();
          } else {
              options.error();
          }
      }
    );
 });

 it("success", function () {
     app.fire("success/url", successFn, errorFn);
     expect(successFn).toHaveBeenCalled();
 });

 it("error response", function () {
     app.fire("error/url", successFn, errorFn);
     expect(errorFn).toHaveBeenCalled();
 });
});

धन्यवाद दोस्त। इस उदाहरण से मुझे बहुत मदद मिली! बस ध्यान दें कि यदि आप जैस्मीन> 2.0 के लिए वाक्यविन्यास का उपयोग कर रहे हैं और CallFake spyOn (jQuery, "ajax") है। और .allFake (/ * अपने फ़ंक्शन * /);
जोओ पाउलो मोटा

यकीन नहीं है कि यह एक संस्करण मुद्दा है, लेकिन मुझे एक त्रुटि मिली है .andCallFake, .and.callFakeइसके बजाय इसका उपयोग किया गया है। धन्यवाद।
OO

5

जब मैं जैस्मीन के साथ अजाक्स कोड निर्दिष्ट करता हूं, तो मैं जो कुछ भी निर्भर करता है, उस पर दूरस्थ कॉल शुरू करता है (जैसे, कहते हैं, $ .get या $ ajax) जासूसी करके समस्या का समाधान करता है। फिर मैं उस पर सेट कॉलबैक को पुनः प्राप्त करता हूं और उन्हें विवेकपूर्वक परीक्षण करता हूं।

यहाँ एक उदाहरण मैंने हाल ही में दिया है:

https://gist.github.com/946704


0

Jqueryspy.com आज़माएं। यह आपके परीक्षणों का वर्णन करने के लिए सिंटैक्स की तरह एक सुरुचिपूर्ण jquery प्रदान करता है और ajax के पूर्ण होने के बाद कॉलबैक को परीक्षण करने की अनुमति देता है। एकीकरण परीक्षण के लिए यह बहुत अच्छा है और आप अधिकतम अजाक्स प्रतीक्षा समय को सेकंड या मिली सेकेंड में कॉन्फ़िगर कर सकते हैं।


0

मुझे ऐसा लगता है कि जैस्मीन के अब संस्करण 2.4 पर होने के कारण मुझे कुछ और जवाब देने की आवश्यकता है और संस्करण 2.0 से कुछ फ़ंक्शन बदल गए हैं।

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

describe("when you make a jQuery AJAX request", function()
{
    it("should get the content of an XML file", function(done)
    {
        var success = jasmine.createSpy('success');
        var error = jasmine.createSpy('error');

        success.and.callFake(function(xml_content)
        {
            expect(success).toHaveBeenCalled();

            // you can even do more tests with xml_content which is
            // the data returned by the success function of your AJAX call

            done(); // we're done, Jasmine can run the specs now
        });

        error.and.callFake(function()
        {
            // this will fail since success has not been called
            expect(success).toHaveBeenCalled();

            // If you are happy about the fact that error has been called,
            // don't make it fail by using expect(error).toHaveBeenCalled();

            done(); // we're done
        });

        jQuery.ajax({
            type : "GET",
            url : "addressbook_files/addressbookxml.xml",
            dataType : "xml",
            success : success,
            error : error
        });
    });
});

मैंने सफलता समारोह के साथ-साथ एरर फंक्शन के लिए भी ट्रिक की है ताकि यह सुनिश्चित हो सके कि जैस्मिन जितनी जल्दी हो सके आपकी ऐनक लौटाएगी या नहीं।

यदि आप एक त्रुटि फ़ंक्शन निर्दिष्ट नहीं करते हैं और आपका AJAX त्रुटि देता है, तो आपको जैस्मिन द्वारा एक त्रुटि फेंके जाने तक 5 सेकंड (डिफ़ॉल्ट टाइमआउट अंतराल) इंतजार करना होगा Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.। आप इस तरह से अपना खुद का टाइमआउट भी निर्दिष्ट कर सकते हैं:

it("should get the content of an XML file", function(done)
{
    // your code
},
10000); // 10 seconds
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.