如何在 Jasmine 单元测试中使用 Sinon 对 jQuery 动画进行假时间?

Posted

技术标签:

【中文标题】如何在 Jasmine 单元测试中使用 Sinon 对 jQuery 动画进行假时间?【英文标题】:How do I fake-time a jQuery animation using Sinon in a Jasmine unit test? 【发布时间】:2011-11-11 13:10:27 【问题描述】:

我有一个 1 秒的 jQuery .animate 操作,在页面加载后 5 秒启动。我在 Jasmine 单元测试代码中设置了一个 Sinon 计时器,并在 7 秒的滴答声后进行测试,以查看动画后的属性是否应有。

它不能正常工作,所以我在 Jasmine html 测试页面上放置了动画本身的一个实例,以便更好地了解发生了什么。

在 Firefox 和 Chrome 中,页面加载,动画函数被调用,单元测试立即失败,然后(也立即)动画可见。

在 IE、Opera 和 Safari 中,页面加载,动画函数被调用,单元测试立即失败,动画从不可见。

我希望的是以下(在所有浏览器中):

页面加载完毕,调用动画函数,动画瞬间完成,单元测试立即成功。

查看Sinon's documentation,它的假计时器涵盖以下过程: setTimeoutclearTimeoutsetIntervalclearIntervalDate

我不知道jQuery的动画是如何工作的,但我想它是使用CSS来过渡的,而CSS过渡在Sinon的useFakeTimers中没有涵盖,所以我想这就是问题所在。但是,如果我对问题的看法是正确的,我仍然需要解决方案。

也许我应该试试诗浓以外的东西? Jasmine 的waits() 在这个测试中完美运行,但对于像我这样没有耐心的人来说非常不切实际。

还有其他建议吗?请记住,我是 JS 单元测试的新手,所以模糊的答案会让我感到困惑,而不是帮助我。 ;o)

【问题讨论】:

已经几天了,没有人回答。为了解决这个问题,我现在正在做的是使用 Jasmine 的 waits() 功能。它运行良好,尽管测试不是即时的,而是实时完成的。嘘。请发布您可能对我有的任何其他想法。谢谢。 嘿!你有没有找到解决这个问题的新方法? $.fx.off 答案完美,但它仍然不是应该的方式...... 我没有。我一直在使用等待()。我实际上已经忘记了这个问题。但是,鉴于 Derek 的解决方案比 Alex 的解决方案更简单,并且它有几票赞成(因此它可能对其他人有用),我会尝试一下,如果它对我有用,则将其标记为答案。 【参考方案1】:

你可以使用jQuery off来关闭jQuery效果:

jQuery.fx.off = true

这不会解决您最初等待事件触发的 7 秒的问题,但这确实意味着您可以测试 DOM 是否已按预期更改。

【讨论】:

【参考方案2】:

我也遇到了同样的问题。我相信这是因为 jQuery 的动画利用了requestAnimationFrame()(如果它可用)而不是依赖于setTimeout()

我已通过将 window 对象上的所有浏览器特定的 requestAnimationFrame 函数设置为 null 来解决此问题:

window.webkitRequestAnimationFrame = null;
window.mozRequestAnimationFrame = null;
window.oRequestAnimationFrame = null;

确保在加载 jQuery 之前执行此代码。

【讨论】:

使用 jasmine + jquery + sinon.js 时,这对我不起作用。我什至确保它在我的任何规范文件甚至 jquery 之前作为 src 依赖项加载。也许我做错了什么?奇怪的是,当我单独运行测试(没有任何其他人)时,它通过了。【参考方案3】:

我认为使用 SinonJs 是可能的,如下所示:https://sinonjs.org/releases/latest/fake-timers/

test("should animate element over 500ms", function () 
   var el = jQuery("<div></div>");
   el.appendTo(document.body);

   el.animate( height: "200px", width: "200px" );
   this.clock.tick(510);

   equals("200px", el.css("height"));
   equals("200px", el.css("width"));
);

【讨论】:

以上是关于如何在 Jasmine 单元测试中使用 Sinon 对 jQuery 动画进行假时间?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jasmine 单独测试 Marionette 模块

在 Angular 中使用 Jasmine 使用 *ngIf 指令时,如何对元素是不是可见进行单元测试

如何对 DOM 操作进行单元测试(使用 jasmine)

如何在 Angular 7 中使用 Karma/Jasmine 为 App_Initializer 编写单元测试用例

如何使用 Jasmine 为私有方法编写 Angular / TypeScript 单元测试

Angular 7:如何在 Jasmine 单元测试中解决 Hammer.js 依赖项