如何在 Jasmine 单元测试中使用 Sinon 模拟 jQuery 动画?

发布于 2024-12-03 03:16:52 字数 933 浏览 2 评论 0原文

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

它无法正常工作,因此我在 Jasmine HTML 测试页上放置了动画本身的一个实例,以便更好地了解发生了什么。

  • 在 Firefox 和 Chrome 中,页面加载,调用动画函数,单元测试立即失败,然后(也立即)明显出现动画。

  • 在 IE、Opera 和 Safari 中,页面加载、调用动画函数,单元测试立即失败,并且动画永远不会明显发生。

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

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

查看Sinon的文档,它的假定时器涵盖了以下流程: setTimeoutclearTimeoutsetIntervalclearIntervalDate

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

或许我应该尝试一下诗乃以外的东西? Jasmine 的 waits() 在此测试中完美运行,但对于像我这样不耐烦的人来说非常不切实际。

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

I have a 1 second jQuery .animate action that launches 5 seconds after page load. I set up a Sinon timer in my Jasmine unit testing code and test after a tick of 7 seconds to see if the post-animation properties are as they should be.

It doesn't work right, so I've placed an instance of the animation itself on my Jasmine HTML test page to better see what's going on.

  • In Firefox and Chrome, the page loads, the animation function is called, the unit test immediately fails, and then (also immediately) the animation visibly occurs.

  • In IE, Opera and Safari, the page loads, the animation function is called, the unit test immediately fails, and the animation never visibly occurs.

What I hoped for was the following (in all browsers):

  • The page loads, the animation function is called, the animation completes instantaneously, and the unit test immediately succeeds.

Looking at Sinon's documentation, it's fake timers cover the following processes:
setTimeout, clearTimeout, setInterval, clearInterval, Date

I don't know how jQuery's animation works, but I imagine it is using CSS to transition, and CSS transitions are not covered in Sinon's useFakeTimers, so I imagine this is the problem. However, if I'm right about the problem I still need a solution.

Maybe I should try something other than Sinon? Jasmine's waits() works perfectly in this test, but is incredibly impractical for impatient folks like myself.

Any other suggestions? Please keep in mind that I am new to JS unit testing, so vague answers will confuse me more than help me. ;o)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怎会甘心 2024-12-10 03:16:52

您可以使用 jQuery off 关闭 jQuery 效果:

jQuery.fx.off = true

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

You can use jQuery off to turn off jQuery effects:

jQuery.fx.off = true

This won't solve your problem of the inital 7 second wait for your event to fire but it does mean you can test that the DOM has been changed as you expected.

墨小沫ゞ 2024-12-10 03:16:52

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

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

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

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

I've had the same problem. I believe it happens because jQuery's animation takes advantage of requestAnimationFrame() if it's available instead relying of the setTimeout().

I've worked around this issue by setting all browser-specific requestAnimationFrame functions on the window object to null:

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

Make sure this code executes before jQuery is loaded.

梦纸 2024-12-10 03:16:52

我认为 SinonJs 是可能的,如下所示: https://sinonjs.org/releases /最新/假定时器/

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"));
});

I think it is possible with SinonJs as it showed here: 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"));
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文