Today I had to write unit tests for JavaScript time dependent code.
I liked that Jasmine supported a way to make setTimeout or setInterval to behave synchronously.
When we install clock with jasmine.clock().install(); into beforeEach
we change behaviour of setTimeout and setInterval functions to be synchronous.
After this we can move forward in time like using time machine and check
result of asynchronous process.
We can go into future with jasmine.clock().tick function, which takes a number of milliseconds.
This is small example code:
1 describe("Jasmine Clock demo", function () { 2 3 // It is installed with a call to jasmine.clock().install 4 // in a spec or suite that needs to manipulate time. 5 beforeEach(function () { 6 jasmine.clock().install(); 7 }); 8 9 // Be sure to uninstall the clock after you are done 10 // to restore the original functions. 11 afterEach(function () { 12 jasmine.clock().uninstall(); 13 }); 14 15 it("setTimeout must behave synchronously", function () { 16 var array = [1, 2, 3, 4, 5, 6]; 17 var sum = 0; 18 (function _handleArray() { 19 sum += array.shift(); 20 if (array.length != 0) { 21 setTimeout(_handleArray, 0); 22 } 23 }()); 24 25 // The cool part 26 // We have something like 27 // time machine and can 28 // move time forward. 29 jasmine.clock().tick(200); 30 // 1 + 2 + 3 + 4 + 5 + 6 31 // is equal to 21 32 expect(sum).toEqual(21); 33 }); 34 }); 35
And here can be viewed this code:
http://gonaumov.github.io/jasmineClockDemo/
running into Jasmine 2.3.4 with spec file.