Jest: Mocking current time for Date

Created on 6 Dec 2016  ·  72Comments  ·  Source: facebook/jest

EDIT by @SimenB 25-05-2020: See updated answer: https://github.com/facebook/jest/issues/2234#issuecomment-633402727

Is there a way to mock the current date? So that new Date() or Date.now() returns a mocked time instead of the current time?

Most helpful comment

For anyone else out there running in to errors with this, I had some issues because global Date object has properties other than constructor. I did the following:

const DATE_TO_USE = new Date('2016');
const _Date = Date;
global.Date = jest.fn(() => DATE_TO_USE);
global.Date.UTC = _Date.UTC;
global.Date.parse = _Date.parse;
global.Date.now = _Date.now;

All 72 comments

Date.now = jest.fn or global.Date = jest.fn().

For anyone else out there running in to errors with this, I had some issues because global Date object has properties other than constructor. I did the following:

const DATE_TO_USE = new Date('2016');
const _Date = Date;
global.Date = jest.fn(() => DATE_TO_USE);
global.Date.UTC = _Date.UTC;
global.Date.parse = _Date.parse;
global.Date.now = _Date.now;

If you do not need to assert on how the constructor is being called then extending could be enough:

const constantDate = new Date('2017-06-13T04:41:20')

/*eslint no-global-assign:off*/
Date = class extends Date {
  constructor() {
    return constantDate
  }
}

This works pretty well for Date.now().

const now = Date.now()
Date.now = jest.genMockFunction().mockReturnValue(now)

Whenever you mock date, don't forget to put back the real version.
Following @callemo comment, you may use the following snippet:

describe('getTimestamp', () => {
  const RealDate = Date

  function mockDate (isoDate) {
    global.Date = class extends RealDate {
      constructor () {
        return new RealDate(isoDate)
      }
    }
  }

  afterEach(() => {
    global.Date = RealDate
  })

  it('should return timestamp', () => {
    mockDate('2017-11-25T12:34:56z')
    expect(getTimestamp()).toEqual('20171125123456')
  })
})

Arguably, Date should also be moved forward when running jest.runTimersToTime() and other time mocking functions. I was bitten by the same issue, since part of my code depended on time, and part on timeouts. Mocking them both at the same time -- i.e. running mocked timers AND switching the Date.now and Performance.now mocks is not the best experience.

A solution for a "unified" timers mock was to use lolex instead of jest builtins, like this:

import lolex from 'lolex'

describe('tests', () => {
  let clock
  beforeEach(() => {clock = lolex.install()})
  afterEach(() => {clock = clock.uninstall()})

  test('garbage collects after keep alive', () => {
    // ...
    clock.tick(500)
    // ...
  })
})

But it would be great to have this feature builtin.

Old issue, but mockdate makes this easy: https://www.npmjs.com/package/mockdate

https://jasmine.github.io/2.2/introduction?spec=jasmine.any#section-Mocking_the_Date

   describe("Mocking the Date object", function(){
     it("mocks the Date object and sets it to a given time", function() {
       var baseTime = new Date(2013, 9, 23);
       jasmine.clock().mockDate(baseTime);
       jasmine.clock().tick(50);
       expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
     });
   });

@drpicox that's a nice solution, however AFAIK it doesn't mock performance.now(), which is a useful, forward-only clock (i.e. won't be set back by user changing his system's DateTime).

In fact it does not work in Jest. Jest uses Jasmine v1.5.2-lite, so it has no clock. I am using lolex.

Date.now() is good enough for most applications, permofrmance.now() it is not present in node yet —cannot be used in SSR for example—, so it does not seems to be a big deal.

Of course, lolex is not integrated with jest.

@drpicox ah, good to know it doesn't work then.
performance.now() is present in node, since v8.5.0 I believe. You can import performance from the builtin module 'perf_hooks'.

Still, given the current situation and the number of votes/comments this is getting, I would like to ping @cpojer to consider re-opening this issue.

FWIW I'd love to integrate lolex - it's the only library I use where I think Jest is missing a battery

@cpojer Any way we can reopen this. As of now, there is not really a way to mock a date AND simulate the pass of time in an easy way.

jasmine has a clock class where you can mock a date AND advance time, via:

jasmine.clock().install(); //in a beforeEach
jasmine.clock().uninstall(); // in a AfterEach
jasmine.clock().mockDate(new Date('1984/12/15'));

// and very important... the pass of time!
jasmine.clock().tick(100);

Would love to have similar functionality native. https://github.com/jasmine/jasmine/blob/master/src/core/Clock.js

We will attempt to migrate to Lolex, which supports your use case. See #5165

In case you need to mock Date _outside_ of a test environment. I needed to take predictable image snapshots of UI where a date is displayed.

This worked for me:
https://github.com/schickling/timemachine

timemachine.config({
  dateString: 'December 25, 1991 13:12:59'
});
console.log(new Date()); // December 25, 1991 13:12:59

@omegdadisc 's suggestion is the best I think. Mocking Date to always return the same date (as it was suggested in the first answers) would mess up with things like new Date(2018, 2, 3) so was not a valid option to me.

Note that you also need to precise the timezone for it to fully work everywhere, e.g. on Travis and produce same result.

timemachine.config({
  dateString: 'December 25, 1991 13:12:59 GMT'
});

The following test stubs Date to return a constant during the test lifecycle.

let timeNow;
const realDate = Date;

describe("Stubbed Date", () => {
  beforeAll(() => {
    timeNow = Date.now();
    const _GLOBAL: any = global;
    _GLOBAL.Date = class {
      public static now() {
        return timeNow;
      }

      constructor() {
        return timeNow;
      }

      public valueOf() {
        return timeNow;
      }
    };
  });

  afterAll(() => {
    global.Date = realDate;
  });

  it("provides constant timestamps", () => {
    const ts1 = Date.now();
    const ts2 = +new Date();
    expect(ts1).toEqual(ts2);
    expect(ts2).toEqual(timeNow);
  });
});

_GLOBAL is just a proxy variable to satisfy typescript.

I needed to mock Date.now()

setting the below line in config or before tests worked for me:

jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000)

I liked @vcarel's approach, but in my case the Date constructor was used with arguments in some cases, so I needed to modify it to accept other dates. I also added Date.now()

describe('getTimestamp', () => {
  const RealDate = Date

  function mockDate (isoDate) {
    global.Date = class extends RealDate {
      constructor(...theArgs) {
        if (theArgs.length) {
          return new RealDate(...theArgs);
        }
        return new RealDate(isoDate);
      }

      static now() {
        return new RealDate(isoDate).getTime();
      }
    }
  }

  afterEach(() => {
    global.Date = RealDate
  })

  it('should return timestamp', () => {
    mockDate('2017-11-25T12:34:56z')
    expect(getTimestamp()).toEqual('20171125123456')
  })
})

I'm using this, which I'm happy with: https://github.com/boblauer/MockDate

I have done this

~~~
describe('Test', () => {
const constantDate = new Date('2018-01-01T12:00:00')

beforeAll(() => {
global.Date = class extends Date {
constructor () {
super()
return constantDate
}
}
})
~~~

Just like to add slightly to @callemo's and @iwarner's answer.

It's probably less error prone to do something like as it returns a new date instance each time:

  const constantDate = new Date('2018-01-01T12:00:00')

  beforeAll(() => {
    global.Date = class extends Date {
      constructor () {
        super(constantDate.getTime())
      }
    }
  })

This allows functions that mutate date objects (e.g. setMinutes) to be used without mutating constantDate and thus altering the date that is returned from new Date e.g.

describe('Test', () => {
  const constantDate = new Date('2018-01-01T12:00:00')

  beforeAll(() => {
    global.Date = class extends Date {
      constructor () {
        super()
        return constantDate
      }
    }
  });

  it('it should not be possible to mutate the  original date but it is.', () => {
    const date1 = new Date();
    date1.setMinutes(5);
    const date2 = new Date();
    console.log(date2.getMinutes()); // Will print 5
  });
});

This is what I'm using after reading all of the above:

let currentDate;

beforeAll(() => {
  currentDate = new Date();

  const RealDate = Date;
  global.Date = jest.fn(() => new RealDate(currentDate.toISOString()));
  Object.assign(Date, RealDate);
});

@samboylett Does this mess up the global date for tests in the future? Did you also reset it in an afterAll function?

It won't affect tests in different files. For me everything in the current file needed the mocked date, but if you need to reset it between tests in the same file you should use a beforeEach and afterEach, and just set it back in the afterEach:

afterEach(() => {
  global.Date = RealDate;
});

@samboylett thanks! I managed to get my date tests working by using your example as a base.

const myDate = new Date(2018, 6, 11);

const RealDate = Date;

describe('testcase', () => {
  beforeEach(() => {
    global.Date = jest.fn(
      (...props) =>
        props.length
          ? new RealDate(...props)
          : new RealDate(myDate)
    );
    Object.assign(Date, RealDate);
  });

  afterEach(() => {
    global.Date = RealDate;
  });
});

Maybe you need jest-date-mock.

Give you simple API to control the current timestamp for you test cases.

import { advanceBy, advanceTo, clear } from 'jest-date-mock';

test('usage', () => {
  advanceTo(new Date(2018, 5, 27, 0, 0, 0)); // reset to date time.

  const now = Date.now();

  advanceBy(3000); // advance time 3 seconds
  expect(+new Date() - now).toBe(3000);

  advanceBy(-1000); // advance time -1 second
  expect(+new Date() - now).toBe(2000);

  clear();
  Date.now(); // will got current timestamp
});

The above solutions did not cover my use case. I did the following based on @callemo which was missing support for instanceof and setting specific dates.

export function mockDate({year = 2017, month = 9, day = 16}) {
    const globalDate = global.Date
    global.Date = class MockDate extends Date {
        constructor() {
            super()
            this.setFullYear(year)
            this.setMonth(month)
            this.setDate(day)
        }
    }
    global.Date.mockRestore = () => global.Date = globalDate
}

@javadoug What's is your case?

@javadoug What's is your case?

@hustcc mockDate() instanceof Date === true.

@javadoug new version jest-date-mock supported. https://github.com/hustcc/jest-date-mock/pull/7

'I don't always mock time, but when I do, it is in jest` - the infamous @satub

I needed to mock new Date() but needed the rest of Date functionalities to work as normal. This is the solution that worked for me.

describe('...', () => {
  const RealDate = Date;

  function mockDate(isoDate) {
    global.Date = class extends RealDate {
      constructor(...args) {
        if (args.length) return new RealDate(...args);
        return new RealDate(isoDate);
      }
    };
  }

  afterEach(() => {
    global.Date = RealDate;
  });

  it('...', () => {
    mockDate('2018-01-01');
    // rest of the code
  });
})

I'm getting error whenever I try to assign to global.Date:

Error: Error: ReferenceError: Date is not defined
    at Object.<anonymous>.exportObject.JUnitXmlReporter.self.specDone (/src/node_modules/jasmine-reporters/src/junit_reporter.js:274:33)
    at dispatch (/src/node_modules/jest-jasmine2/build/jasmine/report_dispatcher.js:70:26)
    at ReportDispatcher.specDone (/src/node_modules/jest-jasmine2/build/jasmine/report_dispatcher.js:62:247)
    at Object.specResultCallback (/src/node_modules/jest-jasmine2/build/jasmine/Env.js:411:18)
    at Spec.attr.resultCallback (/src/node_modules/jest-jasmine2/build/setup_jest_globals.js:67:24)
    at complete (/src/node_modules/jest-jasmine2/build/jasmine/Spec.js:111:10)
    at currentRun.then (/src/node_modules/jest-jasmine2/build/jasmine/Spec.js:107:30)

It looks like the problem is that I'm using JUnit reporter which is executed in the context of the test and is using Date which is already destroyed because anonymous class is destroyed.

So yeah, global Date is messed up when you use suggestions like all of the above. And it is only a problem when you use non-standard reporters.

Reporters shouldn't be executed inside the sandbox. Jasmine reporters might be hooking into some jasmime stuff that's not purposefully supported, though

Oh, so you're saying that this sort of code is not supported?

const jasmine = global.jasmine;
jasmine.getEnv().addReporter(junitReporter)

Error happens here:
https://github.com/facebook/jest/blob/f9fd98fd4e38978e96a86f1c8796593cad7ac470/packages/jest-jasmine2/src/jasmine/ReportDispatcher.js#L63-L72

Correct, you should use
https://jestjs.io/docs/en/configuration#reporters-array-modulename-modulename-options.
E.g. https://github.com/jest-community/jest-junit

@niieani,

A solution for a "unified" timers mock was to use lolex instead of jest builtins, like this:

I tried that example and it resulting in my tests hanging forever (in a CRA which is using [email protected]). Anyone have success using lolex with Jest?

@kentcdodds make sure to not use jest fake timers at the same time. If it still hangs, mind creating an issue with a reproduction? Lolex should definitely work

Yeah, it's working fine for me in an isolated situation, so I'm likely doing something odd elsewhere. Thanks!

If you only need to mock these cases:

new Date()
new Date('2018-09-20T23:00:00Z') 
const currentDate = new Date('2018-09-20T23:00:00Z');
Date = class extends Date {
  constructor(date) {
    if (date) {
        return super(date);
    }

    return currentDate;
  }
}

This is what I'm using after reading all of the above:

let currentDate;

beforeAll(() => {
  currentDate = new Date();

  const RealDate = Date;
  global.Date = jest.fn(() => new RealDate(currentDate.toISOString()));
  Object.assign(Date, RealDate);
});

Thanks @samboylett

This worked for me in mocking new Date()

@petromoldovan is definitely the best answer.

Add a call to mockRestore at the end of the tests to restore the original date:

const dateNowMockFn = jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000);
// ... code with tests
dateNowMockFn.mockRestore();

Improved @vcarel solution a little bit, in case you want the mock to return a Date instance instead of one of the new class:

    const RealDate = Date

    const mockDate = (isoDate) => {
      global.Date = class extends RealDate {
        constructor () {
          return super(isoDate)
        }
      }
    }

    afterEach(() => {
      global.Date = RealDate
    })

I may be tilting at windmills here, but it's worth pointing out the old adage: Don't mock what you don't own. Instead, wrap it in a function. Nowadays it's so convenient with default argument values:

const myFunc = (msg, date = new Date()) => console.log(`${msg}! ${date}`);

Now in production code you can take advantage of the default:

myFunc("Hello"); // => Hello! Fri Mar 22 2019 21:11:26 GMT-0400 (EDT)

And in test code you can pass in the date explicitly, thus mocking it:

myFunc("Hello", dateObj) // => Hello! ...

@yawaramin There are certainly some divergent viewpoints on this. There's a camp that believes tests should live in service of application code, and there's a point past which the tail starts wagging the dog (Pete Hunt has some strong opinions on this)

Not saying that your suggested method isn't a valid option, but rather it perhaps it could be presented as a situationally-appropriate way to go

@cheapsteak I think situational appropriateness is the default state of things. It doesn't hurt to gently remind people that there's always an opportunity to improve testability and that doing so usually improves maintainability :-)

Is there a way to get jest's current time as it is dispatching timers? Something like jest.now?

Suppose I have timers AND calls to Date.now(). I call jest.runAllTimers(). It'd be cool if I could call jest.spyOn(Date, 'now').mockImplementation(() => something) so the timer callbacks run and can check simulated time.

I needed to mock Date.now()

setting the below line in config or before tests worked for me:

jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000)

funny how it works for so many people but not for me. hmm.

I don't know what's going on, but no matter how I reassign Date, Date.now() always exists and always returns a valid value.

Date.now = null does nothing.
global.Date.now = null does nothing.
jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000); does nothing.
Installing and using lolex works on timeouts, but has no effect on Date.now()
MockDate has no effect.

I'm missing something obvious, I think. Maybe another dependency is doing something... so confused.

@mherodev check your test, do you mock date before your test function executes / components render?

Inside a test block I'm doing something like...

      Date.now = () => 1;
      Date = null;
      global.Date = null;
      console.log(`Date.now()`, Date.now()); // Date.now() 1560239936091

But that override does nothing. I find it very confusing.

I followed Hugo's tutorial and ended up doing:

  // @ts-ignore
  .spyOn(global.Date, 'constructor')
  .mockImplementationOnce(() => new Date('2019-06-19T00:07:19.309Z'))

So, new Date() will always return new Date('2019-06-19T00:07:19.309Z')

Update: It appears my Date mocks weren't working because of a bug with how babel is transpiling in my environment. Something related to how we're using @babel/runtime-corejs2

Ultimate Solution: jest-date-mock.

  • install

In your package.json under the jest, create a setupFiles array and add jest-date-mock to the array.

{
  "jest": {
    "setupFiles": ["./__setups__/other.js", "jest-date-mock"]
  }
}
  • usage

Give you simple API to control the current timestamp for you test cases.

import { advanceBy, advanceTo, clear } from 'jest-date-mock';

test('usage', () => {
  advanceTo(new Date(2018, 5, 27, 0, 0, 0)); // reset to date time.

  const now = Date.now();

  advanceBy(3000); // advance time 3 seconds
  expect(+new Date() - now).toBe(3000);

  advanceBy(-1000); // advance time -1 second
  expect(+new Date() - now).toBe(2000);

  clear();
  Date.now(); // will got current timestamp
});

I think: All the other solutions are not systematic, or temporary.

it looks like babel transformation breaks previous workarounds.

My solution is adding a new file named setupMockDate.js

const mockDate = DateClass => {
  function Mock(...args) {
    return args.length === 0
      ? new DateClass(Mock.now())
      : new DateClass(...args)
  }
  Object.setPrototypeOf(Mock, DateClass)
  Mock.prototype = DateClass.prototype
  let now
  Mock.now = () => now === undefined ? DateClass.now() : now
  Mock.mockNow = value => now = value
  Mock.mockRestore = () => Mock.mockNow()
  return Mock
}
global.Date = mockDate(Date)

In jest.config.js at setupFilesAfterEnv entry (or setupFiles in old jest version), add '<rootDir>/jest/setupMockDate.js'.

Now, you are able to run

Date.mockNow(10)
expect(Date.now()).toBe(10)
Date.mockRestore()
expect(Date.now()).not.toBe(10)

Late to the party, but I think jest has all the functionality you need for this.

describe('how to mock date.now()', function() {
  beforeEach(() => {
    this.timestamp = 0
    global.Date.now = jest.fn().mockImplementation(() => this.timestamp)
  })

  afterEach(() => {
    jest.clearAllMocks()
  })

  it('can advance in time', () => {
    const then = Date.now()

    this.timestamp += 1000

    const now = Date.now()

    expect(now - then).toBe(1000)
  })

I'm using vue-moment and jest, and have found the best way is to do something like this:

import { mount, createLocalVue } from '@vue/test-utils';
import TripList from 'components/trip-list.vue';

const localVue = createLocalVue();
localVue.use(require('vue-moment'));

describe('TripList', () => {

it('text shows current date', () => {
    const myDate = new Date(2019, 5, 5);

    const wrapper = mount(TripList, {
      localVue,
    });

    wrapper.vm.$moment.now = () => myDate;
    wrapper.vm.$forceUpdate();

    expect(wrapper.html()).toContain('Thu, Oct 3rd');
  });
})

Using ES6

const fixedDate = new Date('2019-03-1');
const RealDate = Date;

beforeEach(() => { Date.now = () => fixedDate; });
afterEach(() => { global.Date = RealDate; });

If you are using Date.now()

const dateSpy = jest.spyOn(Date, 'now');
dateSpy.mockReturnValue(TIMESTAMP);

For anyone else out there running in to errors with this, I had some issues because global Date object has properties other than constructor. I did the following:

const DATE_TO_USE = new Date('2016');
const _Date = Date;
global.Date = jest.fn(() => DATE_TO_USE);
global.Date.UTC = _Date.UTC;
global.Date.parse = _Date.parse;
global.Date.now = _Date.now;

I wanted to mock the whole Date class and the method suggested by @kristojorg seemed ideal.

I am not sure if this is the appropriate way to do it, but this solutions works fine in TypeScript by fixing the typing issue as mentioned by @nilobarp:

describe('Mock Date', () => {
  const realDateNow = Date.bind(global.Date);

  beforeAll(() => {
    // Fix the time to 2020-1-1 1hr:1min:1sec in order to match
    // snapshots for the DownloadConfirmDialog component.
    const fixedDate = new Date(2020, 0, 1, 1, 1, 1);
    const d = Date;

    // This will only mock any Date objects instantiated with new 
    // and not Date.now().
    const _global: NodeJS.Global = global;
    _global.Date = jest.fn(() => fixedDate);
    _global.Date.parse = d.parse;
    _global.Date.UTC = d.UTC;
    _global.Date.now = d.now;
  });

  it('shows mocked date', () => {
    // Shows 2020-01-01T01:01:01.000Z as the current Date
    // for an instantiated Date object.
    console.log(new Date().toISOString());
  });

  afterAll(() => {
    // Reverts to the current Date object.
    global.Date = realDateNow;
    console.log(new Date().toISOString());
  });
});

It is worth mentioning that this only works when you instantiate a new Date object and will not work for Date.now(). There is a comment regarding Date.now.

Inside a test block I'm doing something like...

      Date.now = () => 1;
      Date = null;
      global.Date = null;
      console.log(`Date.now()`, Date.now()); // Date.now() 1560239936091

But that override does nothing. I find it very confusing.

I am having the same problem: tested a whole bunch of code examples found in this issue and none worked for me: mock appears to be ignored.

How did you fix your problem?

We are also using Babel so this may be related too.

Inside a test block I'm doing something like...

      Date.now = () => 1;
      Date = null;
      global.Date = null;
      console.log(`Date.now()`, Date.now()); // Date.now() 1560239936091

But that override does nothing. I find it very confusing.

I am having the same problem: tested a whole bunch of code examples found in this issue and none worked for me: mock appears to be ignored.

How did you fix your problem?

We are also using Babel so this may be related too.

@warpdesign this solution seems to work for me with Jest in TypeScript.

describe('Mock Date.now', () => {
  // Bind to the original Date so we can set it back after all tests are finished.
  const realDateNow = Date.now.bind(global.Date);

  beforeAll(() => {
    // Return 1 millisecond when calling Date.now() in tests.
    const dateNowStub = jest.fn(() => 1);
    global.Date.now = dateNowStub;
  });

  it('shows mocked date', () => {
    console.log(Date.now());  // Returns 1.
  });

  afterAll(() => {
    // Set back to the original Date object.
    global.Date.now = realDateNow;
    console.log(Date.now()); // Returns current time in milliseconds.
  });
});

From this article on mocking the current Date in Jest.

Ultimate Solution: jest-date-mock.

  • install

In your package.json under the jest, create a setupFiles array and add jest-date-mock to the array.

{
  "jest": {
    "setupFiles": ["./__setups__/other.js", "jest-date-mock"]
  }
}
  • usage

Give you simple API to control the current timestamp for you test cases.

import { advanceBy, advanceTo, clear } from 'jest-date-mock';

test('usage', () => {
  advanceTo(new Date(2018, 5, 27, 0, 0, 0)); // reset to date time.

  const now = Date.now();

  advanceBy(3000); // advance time 3 seconds
  expect(+new Date() - now).toBe(3000);

  advanceBy(-1000); // advance time -1 second
  expect(+new Date() - now).toBe(2000);

  clear();
  Date.now(); // will got current timestamp
});

I think: All the other solutions are not systematic, or temporary.

Thank you it worked !!

I followed Hugo's tutorial and ended up doing:

  // @ts-ignore
  .spyOn(global.Date, 'constructor')
  .mockImplementationOnce(() => new Date('2019-06-19T00:07:19.309Z'))

So, new Date() will always return new Date('2019-06-19T00:07:19.309Z')

What crap is this man. U say Hugo's tutorial and Hugo says yours.... please don't mislead us.

Jest 26 supports mocking Date using modern fake timers: https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers

If you are stuck with trying to mock the Date constructor in TS, try this:

const mockDate = new Date('Tue, 23 Jun 2020 14:34:56');
const RealDate = Date;
(global as any).Date = class extends RealDate {
  constructor() {
    super();
    return mockDate;
  }
};

// test some date related functionality

global.Date = RealDate;

Jest 26 supports mocking Date using modern fake timers: https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers

@SimenB That's great and I just updated to v26 but can't figure out how we use jest to mock the date. The jest docs only talk about how to mock timers so you can test setTimeOut, but how do you do it to mock "new Date()"?

@gregveres Here is an example test suite that sets the system time (Date methods) to a fixed date and handles advancing that time.

const FIXED_SYSTEM_TIME = '2020-11-18T00:00:00Z';

describe('Set Fixed Date', () => {
    beforeEach(() => {
        jest.useFakeTimers('modern');
        jest.setSystemTime(Date.parse(FIXED_SYSTEM_TIME));
    });

    afterEach(() => {
        jest.useRealTimers();
    });

    it('Should reflect fixed date', () => {
        expect(new Date().toISOString()).toEqual(FIXED_SYSTEM_TIME);

        const MS_TO_ADVANCE = 5000;

        jest.advanceTimersByTime(MS_TO_ADVANCE);

        expect(new Date().toISOString()).toEqual(new Date(Date.parse(FIXED_SYSTEM_TIME) + MS_TO_ADVANCE).toISOString());
    });
});

_Update: Included afterEach() per @alexdanilowicz's comment below._

Update from Nov. 2020

_Bolding that ^ as this thread is growing old and linked to a popular stackoverflow post_

@seansullivan Awesome! FYI, correct me if I'm wrong, but I think it would be nice to add an afterEach (or afterAll) to your specs to reset the date back to reality. Just to be safe.

describe('Test', () => {
  // to avoid race conditions between expected and actual date values
  beforeAll(() => {
    jest.useFakeTimers('modern'); // tell Jest to use a different timer implementation.
    jest.setSystemTime(new Date('20 Aug 2020 00:12:00 GMT').getTime())
  });

  afterAll(() => {
    // Back to reality...
    jest.useRealTimers();
  });

@alexdanilowicz Perfect. Yes, I neglected to include the cleanup in my example. I will update with the afterEach() to ensure sanity is maintained for anybody who finds this thread. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

paularmstrong picture paularmstrong  ·  3Comments

hramos picture hramos  ·  3Comments

stephenlautier picture stephenlautier  ·  3Comments

ianp picture ianp  ·  3Comments

Secretmapper picture Secretmapper  ·  3Comments