сделать javascript функцию callback-ish - PullRequest
1 голос
/ 06 июля 2010

у меня есть функция javascript, использующая jquery:

my.namespace.loadSomeStuff = function() {

    $.get('/Services/loadStuff', function(c){
        $("#stuffDiv").html(c);
    });
};

и я пытаюсь написать модульные тесты для этого.

сейчас, так как эта функция на самом деле ничего не возвращает и не загружает некоторые вещи, асинхронные с использованием jquery 'get', мне трудно это протестировать.

По сути, я хотел бы вызвать эту функцию, подождать, пока возвращает что-то, а затем получить доступ к загруженным элементам, чтобы проверить ... что-то вроде:

my.namespace.loadSomeStuff(function(){
    alert('boo');
    assertSame('Login', $("#stuffDiv").find(......);
});

Теперь я создал в шаблоне, который вызывает модульный тест, и он будет загружаться и отображаться правильно, но предупреждение или утверждение никогда не выполняются.

Есть ли способ, которым я могу сделать это, не добавляя тонны дополнительного кода к каждой моей функции?

спасибо т

Ответы [ 2 ]

1 голос
/ 06 июля 2010

Вам нужно добавить аргумент в метод loadSomeStuff, чтобы получить функцию обратного вызова, которую вы вызвали в своем примере кода, а затем намеренно вызвать ее:

my.namespace.loadSomeStuff= function(callback) {
    $.get('/Services/loadStuff', function(c){
        $("#stuffDiv").html(c);
        if (callback!==undefined)
            callback();
    });
};

Я не уверен, что этоСтоит сделать ваш код более сложным просто для поддержки модульных тестов, хотя вы можете утверждать, что добавление обратных вызовов к асинхронным функциям имеет универсальную полезность.

В качестве альтернативы можно использовать тест, использующий приблизительное время ожидания.

Вы можете использовать ajaxSuccess, как упомянуто Ником (возможно, в сочетании с таймаутом и / или также перехватом ajaxError?).Но меня поражает, что это может быть добавление слишком много знаний о реализации для модульного теста.Что если в будущем loadSomeStuff будет изменен, чтобы работать без XMLHttpRequest, или, возможно, использовать его иногда, когда он не кэшируется?Тогда юнит тест сломается.Конечно, вы можете обновить тест, чтобы он соответствовал реализации, но тогда это не очень полезный модульный тест, не так ли?

1 голос
/ 06 июля 2010

Вы можете использовать глобальные события AJAX для этого , например:

$(document).ajaxSuccess(function() {
  assertSame('Login', $("#stuffDiv").find(......));
});

ajaxSuccess произойдет после каждого AJAX-запроса. Если вы хотите событие, которое запускается после завершения всех одновременных запросов, то ajaxStop - это то, что ты после. Оба эти обработчика не обязательно должны быть подключены к вашим AJAX-методам напрямую, их можно выполнить в модульных тестах.

Это обычные события ( полный список здесь ), поэтому вы можете .bind() / .unbind() по мере необходимости, например, при модульном тестировании выше сделано:

$(document).ajaxSuccess(function() {
  assertSame('Login', $("#stuffDiv").find(......));
  $(this).unbind('ajaxSuccess'); //cleanup
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...