понеделник, 5 октомври 2015 г.

Jasmine Clock

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:

TimeoutSpec.js
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.