ajax() : $. ajax({ type: 'POST', url: 'page. php', data: stuff, success: function( data ) { }, error: function(xhr, status, error) { // check status && error }, dataType: 'text' });
jasmine-ajax is a library that lets you define a set of fake responses for Ajax requests made by your application, specify per spec which response should be used, and keep track of the Ajax requests you make so you can make assertions about the results.
AJAX success is a global event. Global events are triggered on the document to call any handlers who may be listening. The ajaxSuccess event is only called if the request is successful. It is essentially a type function that's called when a request proceeds.
I guess there are two types of tests you can do:
Jasmine can help you do both kinds of tests.
Here is a sample of how you can fake the AJAX request, and then write a unit test to verify that the faked AJAX request was going to the correct 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"
});
}
For Jasmine 2.0 use instead:
expect($.ajax.calls.mostRecent().args[0]["url"]).toEqual("/products/123");
as noted in this answer
Here is a similar unit test that verifies your callback was executed, upon an AJAX request completing successfully:
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
});
}
For Jasmine 2.0 use instead:
spyOn($, "ajax").and.callFake(function(options) {
as noted in this answer
Finally, you have hinted elsewhere that you might want to write integration tests that make real AJAX requests - for integration purposes. This can be done using Jasmine's asyncronous features: waits(), waitsFor() and runs():
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
});
}
Look at the jasmine-ajax project: http://github.com/pivotal/jasmine-ajax.
It's a drop-in helper that (for either jQuery or Prototype.js) stubs at the XHR layer so that requests never go out. You can then expect all you want about the request.
Then it lets you provide fixture responses for all your cases and then write tests for each response that you want: success, failure, unauthorized, etc.
It takes Ajax calls out of the realm of asynchronous tests and provides you a lot of flexibility for testing how your actual response handlers should work.
here is a simple example test suite for an app js like this
var app = {
fire: function(url, sfn, efn) {
$.ajax({
url:url,
success:sfn,
error:efn
});
}
};
a sample test suite, which will call callback based on 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();
});
});
When I specify ajax code with Jasmine, I solve the problem by spying on whatever depended-on function initiates the remote call (like, say, $.get or $ajax). Then I retrieve the callbacks set on it and test them discretely.
Here's an example I gisted recently:
https://gist.github.com/946704
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