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 ments 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
});
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 ments 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
});
Share
Improve this question
edited Aug 24, 2012 at 9:21
Lorraine Bernard
asked Aug 23, 2012 at 8:50
Lorraine BernardLorraine Bernard
13.5k23 gold badges85 silver badges138 bronze badges
2 Answers
Reset to default 4Here'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.
There is a jquery plugin that uses sinonjs
with qunit
and provides a much easier way to write ajax tests and get expected results.
Take a look at jqueryspy