Mocking Time with sinon.js
I was writing some tests for an Angular app and ran into a scenario where I needed a page to behave differently if the time of day was before or after 6AM. The logic is simple enough to capture in my controller:
vm.date = moment().subtract(6, 'hours').toDate();
Basically, if it is before 6AM, display the prior day, otherwise display today. However, as I was trying to write a test for this controller the problem came up: how do I take control of the current time to test both scenarios?
I usually use a library called sinon.js (http://sinonjs.org/) for mocking dependencies in my Angular tests. As it turns out, sinon has a feature called useFakeTimers for handling this time-of-day dependent scenario. Using useFakeTimers you can effectively set the time within the context of your test to anything you want. Here is how I was able to simulate page viewing earlier than 6AM:
clock = sinon.useFakeTimers(new Date(2016,2,15).getTime()); //sets date to Mar 15, 2016 at 00:00 clock.tick(60*60*2*1000); //move the fake time ahead to 2AM
By passing in a specific date to useFakeTimers, you can set the date to whatever you want, and the clock.tick() function lets you manipulate the time of day.
ProTip: Remember to call clock.restore() to reset the date/time in the afterEach function of your specs.
Putting it all together
Using the useFakeTimers feature of sinon.js made this a pretty scenario to test.