How to fake jquery.ajax() response?

前端 未结 6 487
孤独总比滥情好
孤独总比滥情好 2020-12-07 20:56

I am writing some QUnit tests for a JavaScript that makes AJAX calls.

For isolation I overwrite $.ajax to write the parameter array of an AJAX call to a

相关标签:
6条回答
  • 2020-12-07 21:00

    This question has a few years and for the new versions of jQuery has changed a bit.

    To do this with Jasmin you can try Michael Falaga's approach

    Solution

      function ajax_response(response) {
        var deferred = $.Deferred().resolve(response);
        return deferred.promise();
      }
    

    With Jasmine

      describe("Test test", function() {
        beforeEach(function() {
          spyOn($, 'ajax').and.returnValue(
            ajax_response([1, 2, 3])
          );
        });
        it("is it [1, 2, 3]", function() {
          var response;
          $.ajax('GET', 'some/url/i/fancy').done(function(data) {
            response = data;
          });
          expect(response).toEqual([1, 2, 3]);
        });
      });
    

    No Jasmine

      $.ajax = ajax_response([1, 2, 3]);
      $.ajax('GET', 'some/url/i/fancy').done(function(data) {
         console.log(data); // [1, 2, 3]
      });
    
    0 讨论(0)
  • 2020-12-07 21:03

    After reading inspired by @Robusto and @Val, I found a method that works:

    //Mock ajax function
    $.ajax = function (param) {
        _mockAjaxOptions = param;
        //call success handler
        param.complete("data", "textStatus", "jqXHR");
    };
    

    Instead of raising the event from any real $.ajax code or by triggering any events, I have my fake ajax object call the function (which is passed in as a parameter to $.ajax()) as part of my fake function.

    0 讨论(0)
  • 2020-12-07 21:03

    Use a closure to override $.ajax with a dummy response

    After trying the accepted answer and the answer posted by user1634074, I devised this simple and flexible blend of the two.

    In its most basic form…

    function ajax_response(response) {
      return function (params) {
        params.success(response);
      };
    }
    $.ajax = ajax_response('{ "title": "My dummy JSON" }');
    

    In the above example, define a function ajax_response() that accepts some JSON string as an argument (or any number of custom arguments useful for simulating a response) and returns an anonymous closure function that will be assigned to $.ajax as an override for unit testing.

    The anonymous function accepts a params argument which will contain the settings object passed to the $.ajax function. And it uses the argument(s) passed to the outer function to simulate a response from the server. In this example, it always simulates a successful response from the server, by simply invoking the success callback and supplying it with the dummy JSON.

    It is easy to reconfigure…

    function ajax_response(response, success) {
      return function (params) {
        if (success) {
          params.success(response);
        } else {
          params.error(response);
        }
      };
    }
    
    // Simulate success
    $.ajax = ajax_response('{ "title": "My dummy JSON." }', true); 
    doAsyncThing(); // Function that calls $.ajax
    
    // Simulate error
    $.ajax = ajax_response('{ "error": "Who is the dummy now?" }', false); 
    doAsyncThing(); // Function that calls $.ajax
    

    Below we can see it in action…

    /* FUNCTION THAT MAKES AJAX REQUEST */
    function doAsyncThing() {
      $.ajax({
        type: "POST",
        url: "somefile.php",
        // data: {…},
        success: function (results) {
          var json = $.parseJSON(results),
              html = $('#ids').html();
          $('#ids').html(html + '<br />' + json.id);
        }
      });
    }
    
    /* BEGIN MOCK TEST */
    // CREATE CLOSURE TO RETURN DUMMY FUNCTION AND FAKE RESPONSE
    function ajax_response(response) {
      return function (params) {
        params.success(response);
      };
    }
    
    var n = prompt("Number of AJAX calls to make", 10);
    
    for (var i = 1; i <= n; ++i) {
      
      // OVERRIDE $.ajax WITH DUMMY FUNCTION AND FAKE RESPONSE
      $.ajax = ajax_response('{ "id": ' + i + ' }');
      doAsyncThing();
    }
    /* END MOCK TEST */
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <p id="ids">IDs:</p>

    0 讨论(0)
  • 2020-12-07 21:11

    Mock $.ajax as needed without disturbing jQuery

    The answers here are good but had a specific need to build out a fake response to a single API call while leaving all other API calls the same until the backend service was built out so I can continue building stuff on the UI.

    The API object uses $.ajax under the hood so you can call an API method like so:

    api.products({ price: { $lt: 150, tags: ['nike', 'shoes'] } })
    .done(function(json) {
      // do something with the data
    })
    .error(function(err) {
      // handle error
    });
    

    This method does the trick:

    function mockAjax(options) {
      var that = {
        done: function done(callback) {
          if (options.success)
            setTimeout(callback, options.timeout, options.response);
          return that;
        },
        error: function error(callback) {
          if (!options.success)
            setTimeout(callback, options.timeout, options.response);
          return that;
        }
      };
      return that;
    }
    

    Then override a single api call without touching $.ajax:

    api.products = function() {
      return mockAjax({
        success: true,
        timeout: 500,
        response: {
          results: [
            { upc: '123123', name: 'Jordans' },
            { upc: '4345345', name: 'Wind Walkers' }
          ]
        }
      });
    };
    

    https://jsfiddle.net/Lsf3ezaz/2/

    0 讨论(0)
  • 2020-12-07 21:19

    Look at the jQuery documentation: You'll see that the Ajax setup provides a number of other conditions that are tested for. If you make them all point to your fakeAjaxSuccess, you might achieve for your objective.

    Alternatively, wrap your $.ajax call into its own function and have whatever calls it simply call your event handler with the fakeAjaxSuccess object.

    0 讨论(0)
  • 2020-12-07 21:24

    I think the link below should help. as for a parameter I am not so sure but it could be .

    $.fn.ajax.success =  function (){
      ///the rest goest here
    }
    

    Override jQuery .val() function?

    0 讨论(0)
提交回复
热议问题