Как правильно модульный тест jQuery. ajax() обещает использовать Jasmine и/или Sinon?
у меня есть довольно простая функция, которая возвращает jQuery .ajax () обещание как таковое:
CLAW.controls.validateLocation = function(val, $inputEl) {
return $.ajax({
url: locationServiceUrl + 'ValidateLocation/',
data: {
'locationName': val
},
beforeSend: function() {
$inputEl.addClass('busy');
}
}).done(function(result) {
// some success clauses
}).fail(function(result) {
// some failure clauses
}).always(function() {
// some always clauses
});
}
по большей части, этот новый интерфейс обещаний работает как мечта и устраняет пирамиды обратного вызова при использовании jQuery .Аякс() отличное. Тем не менее, я не могу для жизни меня выяснить, как правильно проверить эти обещания, используя Жасмин и/или Синон:
вся документация Синон предполагает, что вы используете старую школу обратные вызовы, я не вижу один пример того, как использовать его с обещания / отсрочки
при попытке использовать Жасмин или Синон шпион, чтобы шпионить за $.Аякс, шпион эффективно переписывает обещание, поэтому его
done
,fail
, иalways
предложения больше не существуют в функции ajax, поэтому обещание никогда не разрешает и не выдает ошибку вместо
Я бы очень хотел пример или два, как проверить эти новые jQuery .ajax () обещает с вышеупомянутым тестирование библиотеки. Я довольно интенсивно прочесал сеть и на самом деле ничего не раскопал. Один ресурс, который я нашел, упомянул использование Жасмин.ajax, но я хотел бы избежать этого, если это возможно, поскольку Sinon предоставляет большую часть тех же возможностей из коробки.
4 ответа:
- Это не так уж сложно на самом деле. Достаточно вернуть обещание и решить его в соответствии с вашим делом.
например:
spyOn($, 'ajax').andCallFake(function (req) { var d = $.Deferred(); d.resolve(data_you_expect); return d.promise(); });
для успеха, или
spyOn($, 'ajax').andCallFake(function (req) { var d = $.Deferred(); d.reject(fail_result); return d.promise(); });
на провал.
для Jasmine 2.0 синтаксис немного изменился:
spyOn($, 'ajax').and.callFake(function (req) {});
метод .andCallFake () не существует в Jasmine 2.0
что-то в этом роде / с Синоном и jQuery deferreds
ajaxStub = sinon.stub($, "ajax"); function okResponse() { var d = $.Deferred(); d.resolve( { username: "testuser", userid: "userid", success: true } ); return d.promise(); }; function errorResponse() { var d = $.Deferred(); d.reject({},{},"could not complete"); return d.promise(); }; ajaxStub.returns(okResponse()); ajaxStub.returns(errorResponse());
вот более простой подход с помощью только javascript.
quoteSnapshots: function (symbol, streamId) { var FakeDeferred = function () { this.error = function (fn) { if (symbol.toLowerCase() === 'bad-symbol') { fn({Error: 'test'}); } return this; }; this.data = function (fn) { if (symbol.toLowerCase() !== 'bad-symbol') { fn({}); } return this; }; }; return new FakeDeferred(); }
операторы if внутри каждого обратного вызова-это то, что я использую в своем тесте для успешного выполнения или выполнения ошибок.
решение, данное @ggozad не будет работать, если вы используете такие вещи, как
.complete()
.но, ура, Жасмин сделал плагин, чтобы сделать именно это:http://jasmine.github.io/2.0/ajax.html
beforeEach(function() { jasmine.Ajax.install(); }); afterEach(function() { jasmine.Ajax.uninstall(); }); //in your tests expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url');