How to spy jQuery AJAX request?
jasmine, javascript, jquery
Solution
Here's a walkthrough:
If you use the code in number 2, you are invoking the ajax function on jquery:
return $.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: {
message: message
}
...
after calling this function with those parameters, jQuery returns a jqHR that happens to have a success function defined. That success function is then invoked:
...
}).success(callback);
All is well so far until your jasmine test spies on the ajax function. The same options you used to invoke `$.ajax` are passed to this new spy.
// this is the value of the options parameter
{
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: {
message: message
}
}
When this object is passed, your fake function actually attempts to call `options.success`, which does not exist! Hence the error.
Problem
The following two ways of implementing an ajaxRequest (1) (2) should be equivalent. Having said that: - Why does the unit test (3) that verifies the callback was executed, succeeds in (1) and fails in (2)? - How should I rewrite the test (3) to spy on the success callback in (2)? - If I try to `stub jQuery.ajax` using sinon and the code (2) I get an error. How should I fix it? Please, see the comments in code (3) for more details. (1) ``` ajaxRequest: function (message, callback) { return $.ajax({ url: backendRouter.generate('feedback_send'), type: 'POST', dataType: 'json', data: { message: message }, success: callback }); } ``` (2) ``` ajaxRequest: function (message, callback) { return $.ajax({ url: backendRouter.generate('feedback_send'), type: 'POST', dataType: 'json', data: { message: message } }).success(callback); } ``` (3) ``` it("should execute the callback function on success", function () { spyOn($, "ajax").andCallFake(function(options) { options.success(); }); // If I use the code (2) I get the following error // TypeError: Object #<Object> has no method 'success' var callback = jasmine.createSpy(); ajaxRequest('some message', callback); expect(callback).toHaveBeenCalled(); }); ``` (4) ``` it("makes a GET request for todo items", function () { sinon.stub(jQuery, 'ajax'); backendController.ajaxRequest('some message', sinon.spy()); // Cannot call method 'success' of undefined }); ```