Должен ли jasmine-ajax
вызывать onreadystatechange
с readyState
из 4, если я никогда не вызываю метод send
?
Если приведенное выше поведение не является ожидаемым, как мне использовать jasmine-ajax
, чтобы убедиться, что был вызван метод send
?
Вот тестируемый код:
Loader = (function() {
var loadNames = function(url, success_callback, error_callback) {
var ajax = new XMLHttpRequest();
ajax.open("GET", url);
ajax.onreadystatechange = function () {
console.info("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
};
})();
Вот тест:
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]);
});
});
});
Я удивлен, увидев, что successFunction
вызывается, потому что тестируемый код никогда не вызывает ajax.send()
. Если это ожидаемое поведение библиотеки, то как мне spyOn
базовый ajax
объект, чтобы я мог убедиться, что тестируемый код вызывает send
?
Да, вы не вызываете ajax.send()
, но вы запускаете событие ajax.onreadystatechange
из-за этого фрагмента кода:
jasmine.Ajax.requests.mostRecent().respondWith({
"status": 200,
"contentType": 'application/json',
"responseText": '[1, 2, 4, 3, 5]'
});
Что изменяет состояние готовности и устанавливает состояние готовности в состояние готовности. На самом деле это именно так, как указано в документации: https://jasmine.github.io/2.6/ajax.html
Что касается того, как проверить, действительно ли вызывается xhr.send, этот ТАК ответ объясняет, что вы можете следить за ним, делая следующее в вашем beforeEach:
spyOn(XMLHttpRequest.prototype, 'send');
После раскомментирования части xhr.send() в вашем загрузчике вы можете проверить вызовы методов следующим образом:
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();
});
});
@ Зак, да, это не очень хорошо объяснено, это как бы подразумевается этой частью: jasmine.Ajax.requests.mostRecent().respondWith({ "status": 200, "contentType": 'text/plain', "responseText": 'awesome response' }); expect(doneFn).toHaveBeenCalledWith('awesome response');
. Похоже, это вызывает обратный вызов doneFn
в документации, который эквивалентен вашему successFunction
На этой странице мне не ясно, что
respondWith
вызовет обратный вызов безsend
вызова; но полезно знать, что я наблюдаю ожидаемое поведение. Как бы то ни было, использованиеstubRequest
также приводит к нужному мне поведению.