Mocking moment() and moment().format using jest

后端 未结 7 2109
暗喜
暗喜 2021-02-12 19:46

I\'m unable to mock moment() or moment().format functions. I have states where, currentDateMoment and currentDateFormatted ar

相关标签:
7条回答
  • 2021-02-12 20:23

    You can mock Moment to return a specific date, then format don't have to be mocked.

    jest.mock('moment', () => {
      return () => jest.requireActual('moment')('2020-01-01T00:00:00.000Z');
    });
    

    By doing so, any call to Moment() will always return a moment object with date set to 2020-01-01 00:00:00

    Here is an example with a function that return the date of tomorrow and the test for this function.

    const moment = require('moment');
    const tomorrow = () => {
      const now = moment();
      return now.add(1, 'days');
    };
    
    describe('tomorrow', () => {
      it('should return the next day in a specific format', () => {
        const date = tomorrow().format('YYYY-MM-DD');
        expect(date).toEqual('2020-01-02');
      });
    });
    
    0 讨论(0)
  • 2021-02-12 20:28

    The easiest way to mock moment() and any function that it uses (i.e. .day(), .format()) is to change the Date that moment() uses under the hood

    Add the snippet below inside your test file

    Date.now = jest.fn(() => new Date("2020-05-13T12:33:37.000Z"));

    This makes it so anytime moment() is called in your tests, moment() thinks that today is Wednesday, May 13th 2020

    0 讨论(0)
  • 2021-02-12 20:29

    mockdate works for me

    import mockDate from "mockdate";
    
    
    test('Should add some', () => {
        mockDate.set(new Date('2/20/2020'));
    
        const action = addSome();
    
        expect(action).toEqual({
            createdAt: moment()
        });
    
        mockDate.reset();
    })
    
    0 讨论(0)
  • 2021-02-12 20:33

    Here is the solution:

    index.ts:

    import moment from 'moment';
    
    export function main() {
      return {
        currentDateMoment: moment().format(),
        currentDateFormatted: moment()
          .format('MM-DD-YYYY')
          .valueOf()
      };
    }
    

    index.spec.ts:

    import { main } from './';
    import moment from 'moment';
    
    jest.mock('moment', () => {
      const mMoment = {
        format: jest.fn().mockReturnThis(),
        valueOf: jest.fn()
      };
      return jest.fn(() => mMoment);
    });
    
    describe('main', () => {
      test('should mock moment() and moment().format() correctly ', () => {
        (moment().format as jest.MockedFunction<any>)
          .mockReturnValueOnce('2018–01–30T12:34:56+00:00')
          .mockReturnValueOnce('01–30-2018');
        expect(jest.isMockFunction(moment)).toBeTruthy();
        expect(jest.isMockFunction(moment().format)).toBeTruthy();
        const actualValue = main();
        expect(actualValue).toEqual({ currentDateMoment: '2018–01–30T12:34:56+00:00', currentDateFormatted: '01–30-2018' });
      });
    });
    

    Unit test result with 100% coverage:

     PASS  src/stackoverflow/55838798/index.spec.ts
      main
        ✓ should mock moment() and moment().format() correctly  (7ms)
    
    ----------|----------|----------|----------|----------|-------------------|
    File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    ----------|----------|----------|----------|----------|-------------------|
    All files |      100 |      100 |      100 |      100 |                   |
     index.ts |      100 |      100 |      100 |      100 |                   |
    ----------|----------|----------|----------|----------|-------------------|
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        3.795s, estimated 8s
    

    Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/55838798

    0 讨论(0)
  • 2021-02-12 20:36

    To Mock Moment().format(),startOf() , isValid() or isAfter() etc. Can refer below example.

    jest.mock('moment', () => {
        
        const momentParams = {
            format: jest.fn(() => '10/04/2020'),
            startOf: jest.fn().mockReturnThis(),
            isAfter: jest.fn().mockReturnValue(true),
            isValid: jest.fn().mockReturnValue(true)
        };
    
       const fn = jest.fn(newMoment => {
            momentParams.format = jest.fn(() => newMoment);
            return momentParams;
       });
    
       return fn;
    });
    

    And last you can write a test case like this. eg.

     test('should returned mocked value for isAfter()', async () => {
        jest.spyOn(moment(), 'isAfter').mockReturnValue(false);
        const response = moment().isAfter();
        expect(response).toBe(false)
    })
    
    0 讨论(0)
  • 2021-02-12 20:39

    Don't use import * as moment from 'moment';

    Use the default import

    import moment from 'moment';
    
    // tsconfig.json
    { 
      "compilerOptions": {
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
      }
    }
    

    read

    0 讨论(0)
提交回复
热议问题