Модульное тестирование функции jQuery document.ready - PullRequest
4 голосов
/ 26 ноября 2009

У меня вопрос по модульному тестированию функции document.ready в jQuery ().

В настоящее время у меня есть 2 сценария в моем коде:

function myFunction()
{
    $(document).ready(function() { ... });
}

И

$(document).ready(function()
{
    // some really long setup code here
});

Я пытался написать модульный тест для первого сценария, но я просто не мог заставить его работать в функции document.ready. Что касается второго сценария, у меня пока нет способа проверить его (у меня возникли проблемы с поиском способа проверки и синтаксиса).

Итак, если я не могу изменить исходный код, есть ли способы проверить эти функции? (при условии, что это хорошая идея, чтобы проверить их)

Спасибо.

Ответы [ 3 ]

6 голосов
/ 26 ноября 2009

Вам не нужно тестировать $(document).ready, так как он является частью фреймворка и уже протестирован модулем. При написании юнит-тестов нужно тестировать две вещи:

  1. Ваше взаимодействие с фреймворком. Это включает в себя такие вещи, как проверка правильности вызова функций с правильными параметрами.
  2. Ваш собственный код - ваш код делает правильные вещи.

Итак, что вам действительно нужно сделать, это убедиться, что любой код, который вызывается из $(document).ready, является правильным.

function myInit(){
//...
}
function myFunction()
{
  $(document).ready(myInit);
}

Все, что вам нужно сделать сейчас, это выполнить модульное тестирование myInit функции.

То, что вы также можете сделать, это макетировать функцию $.ready, чтобы убедиться, что вы вызываете ее:

var readyCalled = false;
$.ready = function(func){
  readyCalled = (myInit == func);
}

//Your code containing `myInit` will get executed somewhere here
//....
//Then test:
test("Should have called ready", function() {
 ok(readyCalled, "ready should have been called with myInit as a parameter.")
});
0 голосов
/ 09 декабря 2009

Ответы на этот вопрос см. В сообщениях здесь и здесь .

0 голосов
/ 26 ноября 2009

Функция, которая регистрирует обработчик готовности, должна зарегистрировать другую функцию, а не анонимный кодовый блок. Затем вы можете протестировать код, который вызывает $ .ready (), отдельно от кода, который выполняется на ready. Итак, у вас есть:

  1. Один тест для проверки правильности функции установлен в качестве обработчика готовности
  2. Еще один тест для проверки того, что готовый обработчик делает правильные вещи

Чтобы протестировать сценарий 1, вам нужно ввести двойной тест для jQuery. Это сложно, так как если вы переопределите $ или jQuery, скорее всего, вы испортите другой код, который зависит от него для другой обработки (например, запуска тестов). В то же время ваш код может по-прежнему вызывать jQuery напрямую, когда он использует служебные методы, такие как конкатенация массивов. Любая схема инверсии управления должна учитывать это (http://martinfowler.com/articles/injection.html).

В любом случае, вот некоторый код, использующий инжекцию конструктора (используя JSMock для библиотеки макетов и QUnit (из jQuery) для тестового прогона):

// the code

var createComponent = function(_$) {
    var that = {};

    that.OnStart = function() {
        _$.ready(this.OnReady);
    };

    that.OnReady = function() {
    };

    return that;
};

// the test

test("OnStart associates the ready handler", function() {

   var sut;

   var mock$ = mc.createMock($);
   mock$.expects().ready(isA.TypeOf(Function)).andStub(function(callback) {
        equals(callback, sut.OnReady);
   });

   sut = createComponent(mock$);

   sut.OnStart();

   mc.verify();
});

test("OnReady does the right stuff", function() {
    //etc
});

Я использую этот общий шаблон для всех обработчиков событий в JS ... Вы можете предпочесть использовать классы прототипов. Когда вы передаете функции в качестве параметров в jQuery, вы должны знать, что значение "this" не будет установлено jQuery при вызове этих обратных вызовов. В тесте это прерывается, потому что equals (callback, sut.OnReady) больше не проходит. Чтобы решить эту проблему, нужно, чтобы обработчики событий управляли членами каждого экземпляра. Вы можете вообразить, что когда есть несколько вариантов, приятно иметь утилиту, которая принимает их список, но это демонстрирует превращение OnReady в члена, который не полагается на «this».

var Component = function(_$) {
    this._$ = _$;

    // repeat for each event handler thats tested
    this.OnReady = function() {
        Component.prototype.OnReady.apply(this);
    }
}

Component.prototype.Start = function() {
    this._$.ready(this.OnReady);
}

Component.prototype.OnReady = function() {
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...