С помощью jQuery вы можете использовать объект xhr, который .ajax()
возвращает как обещание, так что вы можете добавить больше обработчиков (см. Ниже), чем только одиночные success
, complete
и error
, которые вы определили вварианты.Поэтому, если ваша асинхронная функция может возвращать объект xhr, вы можете добавить специфичные для теста обработчики.
Что касается URL, то это немного сложнее.Иногда я настраивал очень простой Node-сервер на localhost, который просто обслуживает стандартные ответы, которые были скопированы с реального сервера.Если вы запускаете свой тестовый набор с того же сервера, ваши URL-адреса просто должны быть абсолютными путями для попадания на тестовый сервер, а не на рабочий сервер.И вы также получаете запись самих запросов, так как сервер их видит.Или вы можете сделать так, чтобы тестовый сервер преднамеренно отправлял сообщения об ошибках или неправильных ответах, если вы хотите увидеть, как код обрабатывает его.
Но это, конечно, довольно сложное решение.Проще было бы определить ваши URL в месте, где вы можете переопределить их из набора тестов.Например:
/* in your code */
var X = function () {
this.fire = function () {
return $.ajax({ url: this.constructor.url, ... });
};
};
X.url = "someURL.php"; // the production url
/* in your tests */
X.url = "stub.php"; // redefine to the test url
Кроме того, в QUnit есть функция asyncTest
, которая вызывает для вас stop()
.Добавьте крошечный помощник, чтобы отслеживать, когда начинать снова, и у вас есть довольно хорошее решение.
Вот что я сделал раньше
// create a function that counts down to `start()`
function createAsyncCounter(count) {
count = count || 1; // count defaults to 1
return function () { --count || start(); };
}
// ....
// an async test that expects 2 assertions
asyncTest("testing something asynchronous", 2, function() {
var countDown = createAsyncCounter(1), // the number of async calls in this test
x = new X;
// A `done` callback is the same as adding a `success` handler
// in the ajax options. It's called after the "real" success handler.
// I'm assuming here, that `fire()` returns the xhr object
x.fire().done(function(data, status, jqXHR) {
ok(data.ok);
equal(data.value, "foobar");
}).always(countDown); // call `countDown` regardless of success/error
});
В основном countDown
- этофункция, которая отсчитывает от нуля все, что вы укажете, а затем вызывает start()
.В этом случае есть 1 асинхронный вызов, поэтому countDown
будет отсчитывать от этого.И это будет сделано, когда вызов ajax завершится, независимо от того, как он прошел, поскольку он настроен как обратный вызов always
.
И поскольку asyncTest
говорят, что он ожидает 2 утверждения, он сообщитошибка, если обратный вызов .done()
никогда не вызывается, так как никакие утверждения не будут выполнены.Так что, если звонок полностью провалится, вы тоже об этом узнаете.Если вы хотите что-то записать при ошибке, вы можете добавить обратный вызов .fail()
в цепочку обещаний.