Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moment Doesn't work With Jest #5166

Closed
Brendan-Lucas opened this issue Jul 16, 2019 · 15 comments
Closed

Moment Doesn't work With Jest #5166

Brendan-Lucas opened this issue Jul 16, 2019 · 15 comments

Comments

@Brendan-Lucas
Copy link

Brendan-Lucas commented Jul 16, 2019

Describe the bug
When imported into a development setting import moment from 'moment' allows moment to work effectively and does everything I want it to. However when running jest tests that run over the code that calls moment() I get the following error:
"TypeError: moment_1.default is not a function"
Strangely, Importing it in this way: import * as moment from 'moment' allows functionality in test but not in production. I have looked all through jest's issues and this has been a reported issue however the Jest team is confident the issue is on moment's side.

To Reproduce
Steps to reproduce the behaviour:

  1. make a simple function in a react app which calls moment()
  2. add a jest test which will traverse this path.
  3. run the test.
  4. See error

Expected behaviour
Moment should be callable in both test and production in the same way.

Desktop (please complete the following information):

  • OS: macOS Mojave
  • Testing: Jest -v 24.8.0

Moment-specific environment
moment -v 2.24.0

  • Other libraries in use: TypeScript

Please run the following code in your environment and include the output:
console output when moment is imported the way development expects i.e. import moment from 'moment'

console.log src/resources/timestamping.tsx:4
      Tue Jul 16 2019 10:58:16 GMT-0400 (Eastern Daylight Time)
    console.log src/resources/timestamping.tsx:5
      7/16/2019, 10:58:16 AM
    console.log src/resources/timestamping.tsx:6
      240
TypeError: Cannot read property 'version' of undefined.

console output when moment is imported the way it functions in test i.e. import * as moment from 'moment'

console.log src/resources/timestamping.tsx:4
      Tue Jul 16 2019 11:02:46 GMT-0400 (Eastern Daylight Time)
    console.log src/resources/timestamping.tsx:5
      7/16/2019, 11:02:46 AM
    console.log src/resources/timestamping.tsx:6
      240
    console.log src/resources/timestamping.tsx:8
      2.24.0
@KonradLinkowski
Copy link

KonradLinkowski commented Aug 29, 2019

const moment = require("moment").default || require("moment") is what I came up with, but it only allows use to use moment as a function.
// edit

import * as mom from "moment";
const moment = require("moment").default || require("moment");

Fixes angular / jest problem. But it's still a hack.

@brunano21
Copy link

blem. But it's still a hack.

Thank you sir, that helped.

@marwahaha
Copy link
Member

Is there something the Moment.js side can do here?

@DhrubajitPC
Copy link

I was facing this issue when i was using ts-jest for working with typescript and jest. I ended up using babel for typescript support with jest instead and I don't face it anymore. Perhaps the ts-jest library may be doing something under the hood

@DhrubajitPC
Copy link

DhrubajitPC commented May 21, 2020

after some more searching found the solution here
aurelia/skeleton-navigation#606 (comment)

need to pass in "esModuleInterop": true under compilerOptions in tsconfig.json

@marwahaha
Copy link
Member

@DhrubajitPC glad you found the solution.
Can you add that to our docs?
https://momentjs.com/docs/#/use-it/typescript/

@DhrubajitPC
Copy link

Sure... give me some time :)

@DhrubajitPC
Copy link

hmmm... it already seems to be part of the FAQ
https://github.com/moment/moment/blob/develop/FAQ.md

@AaronDovTurkel
Copy link

It seems I only get this error when I set esModuleInterop to true...
@KonradLinkowski - the hack helped though :)

@lucksp
Copy link

lucksp commented Feb 17, 2021

FWIW, I updated my import to use moment-timezone and Jest is happy now:

import moment from 'moment-timezone';

Not sure what the regular moment package is having issues with.

@ichepurnoy
Copy link

ichepurnoy commented Mar 12, 2021

I've found 2 ways to use moment in Jest. ( for the note: I use Angular). I needed to test a component method that uses 'moment()'.
1)

//    spec.ts file (my testing file)
import moment from 'moment'; 
// import exactly like this, not like   import * as moment from 'moment'.  Otherwise you'll get error "moment is not a function".

beforeEach(() => {
   // Pick any timestamp.  This fix works since moment() uses Date.now() under the hood.
    dateNowSpy = jest.spyOn(Date, 'now').mockImplementation(() => 1487076708000); 
}

afterEach(() => {
    dateNowSpy.mockRestore();
});

it('should call myMethod with moment()', () => {
        const selectSpy = spyOn(myComponent, 'myMethod');
        ... // trigger here the call to myMethod.
        expect(selectSpy).toHaveBeenCalledWith(moment()); // moment() will be called with our mocked date
});

The second option uses npm package MockDate https://www.npmjs.com/package/mockdate
Briefly, it's as follows (apply beforeEach/afterEach yourself)

import moment from 'moment';
import * as MockDate from 'MockDate';

MockDate.set(1434319925275);
expect(selectSpy).toHaveBeenCalledWith(moment());
MockDate.reset();

@aleksandar-b
Copy link

aleksandar-b commented Aug 4, 2021

This hack worked for me and Eslint is not complaining.

import moment = require("moment");

@yanghoxom
Copy link

yanghoxom commented Feb 19, 2022

import moment from 'moment/dist/moment'

For anyone who still have no solution for it
with
jest: 26.6.3
moment: 2.29.1:

@cstuncsik
Copy link

Still having this problem with jest@28.1.0 and moment@2.29.2
I didn't want to change any source or test files so my solution was to add the following mock to setupFilesAfterEnv file:

jest.mock('moment', () => ({
  default: jest.requireActual('moment')
}))

@thais-molica
Copy link

I need to mock this call moment.localeData().firstDayOfWeek().

I've tried this:
jest.mock('moment', () => ({ localeData: jest.requireActual('moment'), }));

But it gives me an error TypeError: momentLocaleData.firstDayOfWeek is not a function

When I try this:
jest.mock('moment', () => ({ localeData: () => { firstDayOfWeek: 0; }, }));

I get this other error: TypeError: Cannot read properties of undefined (reading 'firstDayOfWeek')

How should I fix this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests