Reputation: 6606
Should jasmine-ajax
call onreadystatechange
with a readyState
of 4 if I never call the send
method?
If the above is not the expected behavior, how do I use jasmine-ajax
to verify that the send
method was called?
Here is the code under test:
Loader = (function() {
var loadNames = function(url, success_callback, error_callback) {
var ajax = new XMLHttpRequest();
ajax.open("GET", url);
ajax.onreadystatechange = function () {
console.log("Ready state is " + ajax.readyState);
if (ajax.readyState === 4 && ajax.status === 200) {
success_callback(JSON.parse(ajax.responseText));
} else if (ajax.readyState === 4 && ajax.status !== 200) {
error_callback("There was a problem. Status returned was " + ajax.status);
}
};
ajax.onerror = function () {
error_callback("Unknown error");
};
// Shouldn't removing the call to send prevent
// onredystatechange from being called with readyState 4?
// ajax.send();
};
return {
loadNames: loadNames
};
})();
Here is the test:
describe("Loader", function () {
var successFunction, failFunction;
beforeEach(function () {
jasmine.Ajax.install();
successFunction = jasmine.createSpy("successFunction");
failFunction = jasmine.createSpy("failFunction");
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
describe("#loadNames", function () {
it("Makes a success callback with the data when successful", function () {
Loader.loadNames("someURL", successFunction, failFunction);
jasmine.Ajax.requests.mostRecent().respondWith({
"status": 200,
"contentType": 'application/json',
"responseText": '[1, 2, 4, 3, 5]'
});
// Shouldn't this fail since I never called send?
expect(successFunction).toHaveBeenCalledWith([1, 2, 4, 3, 5]);
});
});
});
I'm surprised to see that successFunction
has been called because the code under test never calls ajax.send()
. If this is the expected behavior of the library, then how do I spyOn
the underlying ajax
object so I can verify that the code under test calls send
?
Upvotes: 2
Views: 112
Reputation: 4176
Yes you are not calling ajax.send()
, but you are triggering the ajax.onreadystatechange
event because of this piece of code:
jasmine.Ajax.requests.mostRecent().respondWith({
"status": 200,
"contentType": 'application/json',
"responseText": '[1, 2, 4, 3, 5]'
});
Which changes the readystate and sets the readystate to done. This is actually exactly as the documentation also states: https://jasmine.github.io/2.6/ajax.html
As for how to check if xhr.send is actually being called, this SO answer explains you can spy on it doing the following in your beforeEach:
spyOn(XMLHttpRequest.prototype, 'send');
After uncommenting the xhr.send() part in your loader you could check for method calls like this:
describe("#loadNames", function () {
it("Makes a success callback with the data when successful", function () {
Loader.loadNames("someURL", successFunction, failFunction);
jasmine.Ajax.requests.mostRecent().respondWith({
"status": 200,
"contentType": 'application/json',
"responseText": '[1, 2, 4, 3, 5]'
});
expect(XMLHttpRequest.prototype.open).toHaveBeenCalled();
});
});
Upvotes: 2