Fake timers
JavaScript code on various platforms makes heavy use of the global timer
functions – setTimeout()
etc. – and when testing such code it’s often good
to be able to take control of the clock to drive a test scenario forward. This
means that, rather than setting your own timeouts in tests to wait for things
to happen, you can tell the clock to tick forward and run your timeouts. This
speeds your tests up and removes some of the line noise of running
asynchronous tests.
JS.Test.FakeClock
lets you stub out JavaScript’s clock and move time forward
yourself. To use it, you need to add the following hooks to your tests:
JS.Test.describe('Timers', function() { with(this) { include(JS.Test.FakeClock) before(function() { this.clock.stub() }) after(function() { this.clock.reset() }) // Your tests here }})
Calling clock.stub()
replaces the global time functions – Date()
,
Date.now()
, setTimeout()
, clearTimeout()
, setInterval()
and
clearInterval()
– with versions that run on a fake clock that you control.
They work just like the real versions, only that time is now controlled by you
rather than by the JavaScript runtime.
When using FakeClock
, timers will not execute unless you advance the clock.
To make time tick forward, use the clock.tick()
method:
// Advances time 1000 milliseconds this.clock.tick(1000)
Let’s take a quick example. This test sets a timeout to change the value of a
string, and we use FakeClock
to test it:
JS.Test.describe('Timers', function() { with(this) { include(JS.Test.FakeClock) before(function() { this.clock.stub() }) after(function() { this.clock.reset() }) before(function() { with(this) { this.string = 'foo' setTimeout(function() { string = 'bar' }, 100) }}) it('changes a string', function() { with(this) { assertEqual('foo', string) clock.tick(100) assertEqual('bar', string) }}) }})