使用qUnit测试.animate的更好方法

时间:2013-09-15 22:46:00

标签: jquery unit-testing tdd qunit

了解TDD我写了一个简单的测试套装,用于向左移动dom元素。

我测试动画我需要等待它们完成。我不想使用promises,因为它感觉像猴子修补,我最终使用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
});

full fiddle

测试在所有jQuery版本上失败,但2.x (edge)

failed
Expected:   
"50px"
Result:     
"49.69220733642578px"
Diff:   
"50px" "49.69220733642578px" 

增加超时持续时间足以使测试通过,所以我认为在探测左边属性之前动画没有完成。

但这似乎不对。必须猜测等待多长时间。 有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

您需要重新构建测试以及方法moveLeft。你现在正在做的是调用.animate(我认为,moveLeft.animate的包装器),然后告诉qUnit在检查元素的左侧位置之前等待101 ms。正如您已经指出的那样,这不是一种非常可靠的测试方法!

相反,您需要利用.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);

Fiddle

作为奖励,您现在拥有一个更灵活的moveLeft函数,可以接受任意回调。 \ O /

答案 1 :(得分:0)

实际上,有更好的方法 - 使用Sinon的假定时器 - http://sinonjs.org/docs/#clock

  1. 在设置初始化假定时器:

    setup: function () { this.clock = sinon.useFakeTimers(); }

  2. 在测试中调用moveLeft()函数后,将假定时器设置为100 ms:

    this.clock.tick(100);

  3. 现在您可以立即测试动画结果,而无需使用异步测试:

    equal(el.css("left"), "50px");