Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set moment timezone in Jest tests

I have the util function that is parsing given date (i.e. '2019-01-28') in specific date format and then using momentJS retrieving beginning of that day and converting it to ISO date format:

dates.js

import moment from 'moment'

export const getApiDateFormat = (date, dateFormat = getLocaleDateString()) =>
    moment(date, dateFormat)
      .startOf('day')
      .toISOString()

I would like to test this function using Jest and set the specific timezone for moment to use those tests independent of my location.

For now, I have:

dates.test.js

const formattedDate = '2019-01-27T23:00:00.000Z'

test('date in russian format - 28.01.2019', () => {
      const russianDateFormat = 'DD.MM.YYYY'
      expect(getApiDateFormat('28.01.2019', russianDateFormat)).toEqual(
        formattedDate,
      )
    })

since I'm currently located in Europe/Warsaw timezone. How to make this test location independent?

I've tried to use jest.mock to replace moment used by getApiDateFormat by moment.tz.setDefault("America/New_York"), however, all my attempts have failed since they have no influence on moment lib imported by getApiDateFormat.

How to solve such a problem and test it properly?

like image 790
yqbk Avatar asked May 23 '19 11:05

yqbk


People also ask

How do you mock a moment date?

Mocking Date. It is used by the moment library to get the current date and time. jest. spyOn(Date, "now"). mockImplementation(() => { return new Date(2022, 1, 11, 10, 10, 0).

Does moment default to UTC?

utc(Date); By default, moment parses and displays in local time. If you want to parse or display a moment in UTC, you can use moment.

Does moment timezone include moment?

Project Status. Moment-Timezone is an add-on for Moment. js.

How to set a static time and timezone for jest/JS?

Ways to set a static time and timezone for Jest/JS 1 Use a library to mock out Date object to return a static date and timezone (we’d recommend MockDate for simple cases, but read on for a breakdown of the alternatives) 2 Mock moment ().format () to return a static string 3 Mock the Date constructor and now () function to return a static time

Does jest mock return the same date in different timezones?

Yes, the result of moment (date).format () is not the same in GMT than in some other timezone, and we don't want our tests to break some CI pipeline. This is the test spec file, where I am using a Jest mock to always return the same date.

How do you run jest tests in the UTC timezone?

Sometimes users run into timezone-based bugs and we want to cover that easily within our test suites. We run all tests in the project by default using one of the proposed answers here, by setting TZ=UTC in the npm script (e.g. TZ=UTC npm run jest. This runs all tests under the UTC timezone.

How do I get the current time in moment JS?

Javascript exposes the built-in Date object which allows for retrieving the current time through construction with no arguments or a call to the now () property. Moment.js is a popular front-end date manipulation library that is commonly used to manipulate, load, format, and shift time. It uses an empty constructor to get the current time.


Video Answer


3 Answers

Use TZ env var...

You can prepend to your package.json so all machines run with the same timezone like so:

  "scripts": {
    "test": "TZ=UTC jest",
    "coverage": "TZ=UTC jest --coverage"
  },
like image 93
ilovett Avatar answered Oct 23 '22 12:10

ilovett


This worked for me

 "scripts": {
   "test": "TZ=UTC jest",
   "coverage": "TZ=UTC jest --coverage"
 }

but ensure "moment-timezone": "^0.5.27" is installed in your npm dependencies

like image 43
Swapnil Navalakha Avatar answered Oct 23 '22 14:10

Swapnil Navalakha


If you wish to set that timezone for all test files, setting the TZ environment should be enough but if you're looking for setting the timezone for a single test file, the following should be enough

import moment from 'moment-timezone'
moment.tz.setDefault('America/New_York')

https://momentjs.com/timezone/docs/#/using-timezones/default-timezone/

like image 2
Gabriel Brito Avatar answered Oct 23 '22 14:10

Gabriel Brito