moment-timezone icon indicating copy to clipboard operation
moment-timezone copied to clipboard

moment-timezone.js – Getting Error When Running in Jest Test

Open friendken opened this issue 7 years ago • 7 comments

Hi moment-timezone team, Firstly, I want to thank you very much for great package.

I got an error using moment-timezone.js. It runs perfectly on a web page, but when I try to implement the test for it, the test result always returns an error like below.

import moment from 'moment-timezone';

class TimezoneCityItem extends React.Component {

  componentDidMount(){
    this.setState({
      time: moment.tz(this.props.timezone)
    })
  }

  render(){
    return (
      <div>{this.state.time.format('HH:mm')}</div>
    )
  }
}

This is timezoneListDummyData:

const timezoneList = [
  { name: 'los-angeles', title: 'Los Angeles', timezone: 'America/Los_Angeles' },
  { name: 'washington', title: 'Washington', timezone: 'America/New_York' },
  { name: 'london', title: 'London', timezone: 'Europe/London' },
  { name: 'dubai', title: 'Dubai', timezone: 'Asia/Dubai' },
  { name: 'hongkong', title: 'Hongkong', timezone: 'Asia/Hong_Kong' },
];

export default timezoneList;

this is code I use on my test file

import React from 'react';
import { shallow } from 'enzyme';
import TimezoneCityItem from '../TimezoneCity.item';
import timezoneList from '/lib/timezoneListDummyData'; // It just an array list of timezone

describe('<TimezoneCityItem />', () => {
   test('Should render TimezoneCityItem correctly', () => {
       const wrapper = shallow(<TimezoneCityItem {...timezoneList[0]} />);
       expect(wrapper).toMatchSnapshot();
   });
});

This is the version of the packages:

"moment": "~2.18.1",
"moment-timezone": "~0.5.13",

This is the error message:

Test suite failed to run
TypeError: Cannot read property 'split' of undefined

  at node_modules/moment-timezone/moment-timezone.js:36:34
  at Object.<anonymous>.moment (node_modules/moment-timezone/moment-timezone.js:14:20)
  at Object.<anonymous> (node_modules/moment-timezone/moment-timezone.js:18:2)
  at Object.<anonymous> (node_modules/moment-timezone/index.js:1:120)
  at Object.<anonymous> (imports/ui/components/mainLayout/TimezoneCity.item.jsx:3:49)
  at Object.<anonymous> (imports/ui/components/mainLayout/TimezoneCity.jsx:3:47)
  at Object.<anonymous> (imports/ui/components/mainLayout/MainLayout.jsx:6:47)
  at Object.<anonymous> (imports/ui/components/mainLayout/__tests__/MainLayout.test.js:3:19)
      at Generator.next (<anonymous>)
      at new Promise (<anonymous>)
      at Generator.next (<anonymous>)
      at <anonymous>

Please help me on this situation Thanks & best regards

friendken avatar Dec 19 '17 10:12 friendken

that's crazy that this bug isn't fixed...

m-vdb avatar Jul 02 '18 13:07 m-vdb

@m-vdb How can I reproduce it? Check pls this my repository, https://github.com/ellenaua/webpack-1/blob/master/src/index.js - can you change it in a way so that I get this error?

ellenaua avatar Jul 02 '18 18:07 ellenaua

sorry @ellenaua I forgot to update my comment here. After spending two hours on this, I finally pinpointed the issue, and it was totally my fault. I was mocking moment explicitly (because I wanted to mock the timezone to UTC). Maybe it can help others if I post it here. Here was my code before:

//  test-setup.js
jest.mock('moment', () => {
  // UTC everywhere
  const moment = require.requireActual('moment');
  return moment.utc;
});

And I finally replaced that code with:

// test-setup.js
moment.tz.setDefault('UTC');

I honestly think that the initial issue report was similar to the one I had since jest auto mocks everything (what a pain...). If you agree, you can close this ✅

m-vdb avatar Jul 03 '18 06:07 m-vdb

I did something similar with mocking moment with moment-timezone:

    let diffMins = updateThreshold + 1;
    jest.mock('moment', () => {
      const mMoment = {
        diff: jest.fn(() => diffMins),
      };
      const fn = jest.fn(() => mMoment);
      fn.version = '2.24';
      fn.tz = jest.fn();
      fn.fn = jest.fn();
      return fn;
    });

osmyn avatar Feb 14 '20 16:02 osmyn

sorry @ellenaua I forgot to update my comment here. After spending two hours on this, I finally pinpointed the issue, and it was totally my fault. I was mocking moment explicitly (because I wanted to mock the timezone to UTC). Maybe it can help others if I post it here. Here was my code before:

//  test-setup.js
jest.mock('moment', () => {
  // UTC everywhere
  const moment = require.requireActual('moment');
  return moment.utc;
});

And I finally replaced that code with:

// test-setup.js
moment.tz.setDefault('UTC');

I honestly think that the initial issue report was similar to the one I had since jest auto mocks everything (what a pain...). If you agree, you can close this ✅

// test-setup.js moment.tz.setDefault('UTC');

This works like a charm.

dtahoa avatar Jun 04 '20 15:06 dtahoa

Doesn't work for me :( Tests passes but the log is angry.

moment: 2.26.0 moment-timezone: 0.5.3 (with data included)

image

edit: adding image + info

testacode avatar Jun 16 '20 20:06 testacode

@testacode try to setup test like this: // test-setup.js moment.tz.setDefault('UTC');

dtahoa avatar Jun 18 '20 07:06 dtahoa

I'm going to close this as it looks like the initial problem was solved. Since the answer appears to be "change the way Jest mocks are handled", there's nothing to be done in Moment Timezone itself.

gilmoreorless avatar Feb 25 '23 04:02 gilmoreorless