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 variable. This works to test how methods use AJAX functions, but I have difficulty testing the success handler of $.load()
From the documentation at http://api.jquery.com/load/:
When a successful response is detected (i.e. when textStatus is "success" or "notmodified"), .load() sets the HTML contents of the matched element to the returned data.
So I have attempted to return an object containing objects with the same name as variables for the success handler:
//Mock ajax function
$.ajax = function (param) {
_mockAjaxOptions = param;
var fakeAjaxSuccess = { responseText: "success", textStatus: "success", XMLHttpRequest: "success" };
return fakeAjaxSuccess;
};
But this approach hasn't worked.
How can I replicate the behaviour of a successful AJAX call?
When you want to mock out all ajax calls across an entire suite, use install() in a beforeEach . Because jasmine-ajax stubs out the global XMLHttpRequest for the page, you'll want to uninstall() in an afterEach so specs or setup that expect to make a real ajax request can. Make your requests as normal.
If someone has complete access to a browser, then they can run any code they like in it - including modifying or adding JavaScript to your pages. That has absolutely nothing to do with a site using Ajax though — any point where the client interacts with the server may be vulnerable.
processData. If set to false it stops jQuery processing any of the data. In other words if processData is false jQuery simply sends whatever you specify as data in an Ajax request without any attempt to modify it by encoding as a query string.
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]
});
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.
$.ajax
with a dummy responseAfter 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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With