How do I fake-time a jQuery animation using Sinon in a Jasmine unit test?
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 s开发者_运维技巧omething 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)
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.
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.
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"));
});
精彩评论