2013-05-20 2 views
2

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

http://jsfiddle.net/samselikoff/hhk6u/3/

Оба испытания требуют companies, но я не знаю, как изолировать события. Есть идеи?

Ответ:

Jeferson правильно. Один простой способ решить эту проблему - использовать events.once вместо events.on. Таким образом вы очищаете свои события от каждого теста.

+0

не может воспроизводить (каждый раз дает OK). протестирован на хроме 26.0.1410.63 и firefox 21.0 –

+0

действительно? Я получаю каждый другой, который проходит/терпит неудачу. Я получаю сообщение об ошибке: 'start()' уже запущен. Второй тест слышит событие от обеих переменных 'company'. Не следует ли сначала уничтожить первую, после того как она выпадет из сферы действия? Я чувствую, что здесь есть что-то фундаментальное. –

ответ

2

Вы используете синхронные тесты, в то время как обратные вызовы инициируемых событий асинхронны.

Чтобы исправить это, вы должны реализовать «asyncTest» и вызвать функцию запуска, когда утверждения теста готовы к сбору.

Ваш второй тест был сбой с сообщением:

Called start() while already started (QUnit.config.semaphore was 0 already)

Teste Точно уже потому, что это был синхронный тест, началась, и вы вызова метода запуска() еще раз.

А также в вашем первом тесте, который не указывает функцию обратного вызова, вы должны обернуть асинхронный вызов другой функцией, чтобы вы могли вызвать start(), когда имитированный вызов AJAX готов.

Я обновил свой JSFiddle с рабочим кодом: http://jsfiddle.net/hhk6u/8/ новый код:

QUnit.config.autostart = false; 
QUnit.config.testTimeOut = 1000; 

asyncTest('Some test that needs companies.', function() { 
    function getCompanies() { 
     var companies = new Companies(); 
     ok(1); 
     start(); 
    } 
    setTimeout(getCompanies, 500); 
}); 

asyncTest('Some other async test that triggers a listener in companies.', function() { 
    var companies = new Companies(); 

    events.trigger("userSet:company", { name: "Acme", id: 1 }); 

    stop(); 
    events.on('fetched:departments', function(response) { 
     console.log(response); 
     deepEqual(response, [1, 2, 3]); 
     start(); 
    }); 
}); 

Обратите внимание, что в первом методе испытаний я создал функцию «getCompanies», которая будет вызвана после перерыва (500 миллисекунд), который должен быть достаточным для завершения вызова AJAX.

Вы должны отрегулировать это время в соответствии с вашими потребностями, а также изменить значение «testTimeOut», чтобы ваши методы не выполнялись бесконечно.

См QUnit конфигурация Документы для получения более подробной информации: http://api.qunitjs.com/QUnit.config/

+0

Но первый тест не был асинхронным.Вы говорите, что если один из ваших тестов - асинхронный, все они должны быть? Это не так. –

+0

Я не говорю, что все тесты должны быть асинхронными. Ни за что! Дело в том, что первый симулирует запрос AJAX с задержкой тайм-аута, поэтому, когда вы запускаете первый тест в качестве теста синхронизации, он заканчивается перед тем, как завершилась функция вызова «новых компаний()». Тогда ваш второй метод начнется и завершится неудачно. Проблема заключается не в том, что у нас есть два метода тестирования и один асинхронный. Проблема в том, что обе вызовы имеют одну и ту же функцию, и эта функция является асинхронной. – jfoliveira

+0

Я в замешательстве ... 'new Companies()' является функцией async? У него есть слушатель, который отвечает функцией async, но почему он все равно слышит событие во втором тесте? Я решил, что он будет уничтожен после того, как он выйдет за рамки, после завершения первого теста. –

1

не ваш первоначальный Fiddle потенциально неудачи, потому что вы не создаете свой автобус событий в начале каждого испытания (в методе установки()), так что ваши асинхронное событие из первого теста может быть запущено, когда 2-й тест запущен, а затем заставить второй тест обрабатывать его дважды, вызывая start() дважды.

Просмотреть мой обновленный Fiddle http://jsfiddle.net/e67Zh/ он создает автобус событий каждый раз.

Возможно, вы захотите также установить тайм-аут в ваших тестах qunit для сценариев, в которых событие не срабатывает.

/* Backbone code 
*******************/ 
var Company = Backbone.Model.extend({}); 

var Companies = Backbone.Collection.extend({ 

    initialize: function() { 
     var self = this; 

     events.on("userSet:company", function(company) { 
      self.selectedCompany = company; 

      // Simulate an AJAX request 
      setTimeout(function() { 
       events.trigger("fetched:departments", [1, 2, 3]); 
      }, 500); 
     }); 
    }, 

    selectedCompany: '' 
}); 


/* Tests 
*******************/ 

module("test with new event bus each time", { 
    setup: function() { 
     events = _.clone(Backbone.Events); 
    } 
}); 

test('Some test that needs companies.', function() { 
    var companies = new Companies(); 
    ok(1); 
}); 

test('Some other async test that triggers a listener in companies.', function() { 
    var companies = new Companies(); 

    events.trigger("userSet:company", { name: "Acme", id: 1 }); 

    stop(); 
    events.on('fetched:departments', function(response) { 
     console.log(response); 
     deepEqual(response, [1, 2, 3]); 
     start(); 
    }); 
}); 
+0

Интересно, это, наверное, то, чего мне здесь не хватало. С тех пор я перешел к Jasmine, что дает мне понять, как настроить такие модули (например, использовать 'beforeEach'). Благодаря! –

Смежные вопросы