Лучший способ проверить.animate с помощью qUnit
Знакомство с TDD я написал простой тестовый костюм для переезда dom
элементы слева.
Я тестирую анимации, мне нужно дождаться их завершения. Я не хотел использовать обещания, потому что это похоже на исправление обезьян, и в итоге я использовал пример формы qUnit:
test("move 50", function () {
//Creates an element for testing and attaches to document
var el = appendToTest();
ok(el.css('left') == "auto", "element 0");
stop();
moveLeft(el, 50, 100);
setTimeout(function () {
equal(el.css("left"), "50px");
start();
}, 101);//Timeout duration
});
Тест не пройден на всех версиях jQuery, но 2.x (edge)
failed
Expected:
"50px"
Result:
"49.69220733642578px"
Diff:
"50px" "49.69220733642578px"
Увеличение длительности тайм-аута делает тест успешным, поэтому я подумал, что анимация не закончилась, пока не было проверено левое свойство.
Но это не кажется правильным. Нужно угадать, как долго ждать. Есть лучший способ сделать это?
2 ответа
Вы должны реструктурировать свой тест, а также метод moveLeft
, То, что вы в настоящее время делаете, вызывает .animate
(Я предполагаю, moveLeft
это обертка вокруг .animate
) и затем говорит qUnit подождать 101 мс, прежде чем проверять левую позицию элемента. Как вы уже заметили, это не очень надежный способ тестирования!
Вместо этого вам нужно воспользоваться способностью .animate
вызывать функцию обратного вызова, когда она завершится; так что вы измените свой moveLeft
функция для принятия этого обратного вызова, который вы определяете как
function() {equal(el.css("left"), "50px");start();}
и вы передаете этот обратный вызов .animate
в вашем moveLeft
функция
например, ваш звонок теперь выглядит так:
//tells qUnit to expect that one assertion will happen.
//this will mean that your test will also fail if moveLeft doesn't invoke the callback.
expect(1);
//define the calback function
var callback = function(){equal(el.css("left"), "50px");start();}
//execute the test:
moveLeft(el, 50, 100,callback);
скрипка
И в качестве бонуса, теперь у вас есть гораздо более гибкий moveLeft
функция, которая может принять любой произвольный обратный вызов. \ О /
На самом деле, есть лучший способ сделать это - использовать поддельные таймеры Синона - http://sinonjs.org/docs/
В настройках инициализируйте фальшивые таймеры:
setup: function () { this.clock = sinon.useFakeTimers(); }
После звонка
moveLeft()
в тесте установите поддельный таймер на 100 мс:this.clock.tick(100);
Теперь вы можете проверить результат анимации сразу, не используя асинхронный тест:
equal(el.css("left"), "50px");