javascript - Jest mock moment() to return specific date - Stack Overflow

I know this question has been asked multiple times.But I could not find the correct one for my case.I

I know this question has been asked multiple times.

But I could not find the correct one for my case.

I would like to mock the moment() to return a specific date.

First, I mock by

jest.mock("moment", () => {
  return (date: string) =>
    jest.requireActual("moment")(date || "2021-01-01T00:00:00.000Z");
});

But I use some properties of moment, (moment.duration()... for example) So when mock like this, it does not work.

Next I tried to mock Date.now by several ways:

jest.spyOn(Date, "now").mockReturnValue(+new Date("2021-01-01T00:00:00.000Z"));
Date.now = jest.fn(() => +new Date("2021-01-01T00:00:00.000Z")

But when doing this, when calling moment() it returns an invalid date.

I'm not sure what I am doing wrong.

I know this question has been asked multiple times.

But I could not find the correct one for my case.

I would like to mock the moment() to return a specific date.

First, I mock by

jest.mock("moment", () => {
  return (date: string) =>
    jest.requireActual("moment")(date || "2021-01-01T00:00:00.000Z");
});

But I use some properties of moment, (moment.duration()... for example) So when mock like this, it does not work.

Next I tried to mock Date.now by several ways:

jest.spyOn(Date, "now").mockReturnValue(+new Date("2021-01-01T00:00:00.000Z"));
Date.now = jest.fn(() => +new Date("2021-01-01T00:00:00.000Z")

But when doing this, when calling moment() it returns an invalid date.

I'm not sure what I am doing wrong.

Share Improve this question asked Jul 1, 2021 at 11:05 Tan DatTan Dat 3,1171 gold badge21 silver badges39 bronze badges 1
  • See if How to mock moment.utc() for unit tests? and linked questions can be useful to you. – VincenzoC Commented Jul 1, 2021 at 14:31
Add a ment  | 

3 Answers 3

Reset to default 4

Mock the moment() function and its returned value. Use jest.requireActual('moment') to get the original module. Copy its properties and methods to the mocked one.

E.g.

index.js:

import moment from 'moment';

export function main() {
  const date = moment().format();
  console.log('date: ', date);
  const duration = moment.duration(2, 'minutes').humanize();
  console.log('duration: ', duration);
}

index.test.js:

import { main } from '.';
import moment from 'moment';

jest.mock('moment', () => {
  const oMoment = jest.requireActual('moment');
  const mm = {
    format: jest.fn(),
  };
  const mMoment = jest.fn(() => mm);
  for (let prop in oMoment) {
    mMoment[prop] = oMoment[prop];
  }
  return mMoment;
});

describe('68209029', () => {
  it('should pass', () => {
    moment().format.mockReturnValueOnce('2021-01-01T00:00:00.000Z');
    main();
  });
});

test result:

 PASS  examples/68209029/index.test.js (8.914 s)
  68209029
    ✓ should pass (20 ms)

  console.log
    date:  2021-01-01T00:00:00.000Z

      at Object.main (examples/68209029/index.js:5:11)

  console.log
    duration:  2 minutes

      at Object.main (examples/68209029/index.js:7:11)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.726 s

Take a look at the logs, we mocked the returned value of moment().format() correctly and keep using the original implementation of moment.duration(2, 'minutes').humanize() method.

Additional to @slideshowp2's answer.

Just wanted to add another way for this:

jest.mock("moment", () => {
  // Require actual moment
  const actualMoment = jest.requireActual("moment");

  // Mocking moment func: 
  // moment() => return specific date, and it won't affect moment(date) with param.
  const mockMoment: any = (date: string | undefined) =>
    actualMoment(date || "2021-01-01T00:00:00.000Z");

  // Now assign all properties from actual moment to the mock moment, so that they can be used normally
  for (let prop in actualMoment) {
    mockMoment[prop] = actualMoment[prop];
  }
  return mockMoment;
});

you can do it like this too

jest.mock('moment', () => {
    const originalModule = jest.requireActual('moment')

    return {
        __esModule: true,
        ...originalModule,
        default: () => originalModule('2023-06-23')
    }
})

I try it on jest v29.3

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744256343a4565417.html

相关推荐

  • javascript - Jest mock moment() to return specific date - Stack Overflow

    I know this question has been asked multiple times.But I could not find the correct one for my case.I

    8天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信