When unit testing functions that use the Date.now() function, you’ll need to lock down the value it returns – otherwise, your unit tests will only ever run successfully on the day (or even the minute!) that you run them. This article shows how you can override Date.now() to make it return a predictable value.

Step 1. Choose a constant value you want your overridden Date.now() to return.

Because Date.now() returns the number of milliseconds that have elapsed since January 1st 1970, you’ll need to work out the date you want to return (i.e. what you want ‘now’ to be) as a value in milliseconds since this time as well.

The simplest way to do this is simply to console log what Date.now() returns, er, now!

i.e., run this:

console.log(Date.now());

I did this today, and got the value 1462361249717, which represents May 4th 2016.

Step 2. Return this value in a function
function mockDateNow() {
   // mock now = 1462361249717ms = 4th May 2016
   return 1462361249717;
}
Step 3. Make a reference to the existing Date.now() function
const originalDateNow = Date.now;
Step 4. Assign Date.now to your mockDateNow function<.h5>

Date.now = mockDateNow;
Step 5. Write your unit tests

Safe in the knowledge that Date.now() will always return 4th May 2016

Step 6. Return Date.now() to its original function
Date.now = originalDateNow;

Simple!

Putting it all together

The function to test:

function getToday() {
   return Date.now();
}

The tests themselves (using Mocha and Chai):

describe('Mocking Date Now', function() {

   beforeEach(function () {
      originalDateNow = Date.now;
      Date.now = mockDateNow;
   });

   afterEach(function () {
      Date.now = originalDateNow;
   });

   describe('Date functions', function () {
      it('should return today\'s mock date', function () {
         expect(getDayMonth(getToday())).to.equal('4 May');
      });
   });
});

// Pin Date.now() to a specific time in ms
function mockDateNow() {
   // mock now = 1462361249717ms = 4th May 2016
   return 1462361249717;
}

//Date helper function
function getDayMonth(ms) {
   const dt = new Date(ms);
   const monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 
                        'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

   return dt.getDate()  + ' ' + monthNames[dt.getMonth()];
}

There are no comments.

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>