-
-
Save bbshih/1cac2e30e5884102a66a07fbe464b50c to your computer and use it in GitHub Desktop.
// To mock globally in all your tests, add to setupTestFrameworkScriptFile in config: | |
// https://facebook.github.io/jest/docs/en/configuration.html#setuptestframeworkscriptfile-string | |
jest.mock('moment', () => { | |
const moment = require.requireActual('moment-timezone'); | |
moment.tz.setDefault('America/Los_Angeles'); // Whatever timezone you want | |
return moment; | |
}); |
@bbshih this gist is lit!!! Thank you.
Thanks @c58 your update fixed it for me! It seems when updating to Jest 23 the original method stops working and you have to use doMock.
Anyone know the reason?
I just use it as @c58 says and works perfectly, thank you
I had an issue related to this and wanted to share my problem:
In my jest.config, I had
'^moment': '/node_modules/moment'
But it was too permissive and matched moment-timezone as well. Needless to say, great confusion occurred.
The correct config is and exact match regular expression:
'^moment$': '/node_modules/moment'
Hope this helps others.
Using jest.doMock
instead of jest.mock
has helped me.
// To mock globally in all your tests, add to setupTestFrameworkScriptFile in config:
// https://facebook.github.io/jest/docs/en/configuration.html#setuptestframeworkscriptfile-string
jest.doMock('moment', () => {
const moment = require.requireActual('moment-timezone');
moment.tz.setDefault('America/Los_Angeles'); // Whatever timezone you want
return moment;
});
Nice one. Thanks.
Is it right solution to use separate package for setting timezone? I don't understand from where moment gets timezone, tried to mock Date.prototype.getTimezoneOffset
, but looks like moment don't uses it. Also founded that for negative offset tests not fails, only if my offset is more than 0 tests fails.
I had to use require instead of requireActual otherwise I would get moment.tz === undefined
const moment = require('moment-timezone');
jest.doMock('moment', () => {
moment.tz.setDefault('Asia/Yekaterinburg');
return moment;
});
Add the following before describe
in your test
const moment = require.requireActual('moment-timezone').tz.setDefault('America/Los_Angeles');
If you are using guess
to check use current timezone, you also need to mock it:
jest.mock('moment-timezone', () => {
const momentMock = require.requireActual('moment-timezone');
momentMock.tz.setDefault('America/Los_Angeles'); // Whatever timezone you want
momentMock.tz.guess = () => 'America/Los_Angeles'; // Whatever timezone you want
return momentMock;
});
I noticed that requireActual of module A (in our case moment-timezone) inside the mock of module B (moment) returns an empty object.
jest.mock('moment', () => {
const moment = require.requireActual('moment-timezone')
console.log(require.requireActual('moment-timezone')) // logs {}
console.log(require.requireActual('moment')) // logs the actual moment library
})
Anybody facing the same problem ?
@adica - that code worked for me! The only issue I ran into thereafter (removed my manual import of moment-timezone
in the spec file) was not being able to call moment()
for new dates in my spec file; ended up using a different approach there.
Had the same error as @a-reda, the following code worked for me:
// setup.js
const moment = require('moment-timezone')
moment.tz.setDefault('Antarctica/Vostok') // Whatever timezone you want
jest.setMock('moment', moment)
This gist was of great help to me. I found another way of mocking the timezone with a fixed value.
jest.mock('moment', () => () => (jest.requireActual('moment-timezone')).tz('2021-01-01T00:00:00.000Z', 'GMT'));
Hi i tried const moment = require('moment-timezone')
moment.tz.setDefault('Antarctica/Vostok') // Whatever timezone you want
jest.setMock('moment', moment)
it is giving me original user's time zone not the mocked one
any one please help me
export class DateTzPipe implements PipeTransform {
transform(x: any) {
const y = moment.tz(x, 'America/Panama').format();
const errorDate = new Date(y);
const timeZoneString = moment.tz.guess() === 'Pacific/Port_Moresby' ? 'CHST' : moment.tz(moment.tz.guess()).format('z');
return (moment.tz(errorDate,moment.tz.guess()).format('MM/DD/YYYY - hh:mm:ss A') + " " + timeZoneString);
}
test:
const moment = require('moment-timezone')
moment.tz.setDefault('America/New_york') // Whatever timezone you want
jest.setMock('moment', moment)
describe('transform', () => {
let datePipe:DateTzPipe;
beforeEach(() => {
datePipe=new DateTzPipe();
});
it('Should transform measures without a strat expression', () => {
expect(datePipe.transform('2021-09-07T19:23:44.309871')).toBe('09/07/2021 - 08:23:44 PM EDT');
});
If you're still struggling with timezones, try this https://www.npmjs.com/package/timezone-mock it saved my day.
@pimlie thank you! Your solution works
None of these worked for me. I realized this is simply the wrong approach (depending on what you need).
I ended up doing this instead:
test('test thing', () => {
jest.useFakeTimers();
jest.setSystemTime(new Date('2023-01-01'));
expect(fn).toEqual(thing);
jest.setSystemTime(new Date());
});
IMHO, it is best to avoid monkey-patching moment.
@testacode I have the same issue, and this works for me...