首页 > 解决方案 > 如何在开玩笑测试中模拟 moment()

问题描述

我需要使用 jest 和 moment 进行一些测试。一些导入的函数适用于当前日期 (moment() )。但是我似乎无法找到一种始终运行相同日期来测试或模拟时刻构造函数的方法,例如在时刻('2020-07-05')的固定时刻日期,即使当天是 2020-07-10,因此测试应始终在第 5 天下运行。

我的 ./UtilsModule 文件:

import moment from 'moment'
export const getIntervalDates = groupOfDates => {
   const CURRENT_DATE = moment().format('YYYY-MM-DD');
   return getDates(CURRENT_DATE, groupOfDates ) //another function that does some extra processing;
};

export const nextDates = (date, group) => {
  let newDate= getIntervalDates(group);
}

我的 test.js 文件,以及我尝试的内容:

import { nextDates ,getIntervalDates } from '../UtilsModule';
it('testing function', () => {
      const PAYLOAD = {...};
      const DATE= '2020-07-20';

      const SpyGetIntervalDates = jest.spyOn(UtilsModule, 'getIntervalDates');
      SpyGetIntervalDates.mockImplementation(() => Promise.resolve({ minAge: '2020-08-04' }));

      const nextDate = UtilsModule.nextDates(DATE, PAYLOAD);
      expect(nextDate).toEqual({ minDate: '2020-11-04' });
    });

我也试过了,但我无法让它工作:

jest.mock('moment', () => {
  return () => jest.requireActual('moment')('2020-07-04');
});

and
global.moment = jest.fn(moment('2021-07-04'));

标签: javascriptunit-testingtestingjestjsmomentjs

解决方案


您正在尝试nextDates使用模拟函数测试getIntervalDates函数。您需要进行一些重构,您应该为getIntervalDates内部调用的函数保留相同的引用nextDates。然后,您可以使用jest.spyOn替换getIntervalDates为模拟的。

例如

utilsModule.js

import moment from 'moment';

function getDates() {}

const getIntervalDates = (groupOfDates) => {
  const CURRENT_DATE = moment().format('YYYY-MM-DD');
  return getDates(CURRENT_DATE, groupOfDates);
};

const nextDates = (date, group) => {
  return exports.getIntervalDates(group);
};

exports.getIntervalDates = getIntervalDates;
exports.nextDates = nextDates;

utilsModule.test.js

const UtilsModule = require('./utilsModule');

describe('62736904', () => {
  it('testing function', async () => {
    const PAYLOAD = {};
    const DATE = '2020-07-20';

    const SpyGetIntervalDates = jest.spyOn(UtilsModule, 'getIntervalDates');
    SpyGetIntervalDates.mockImplementation(() => Promise.resolve({ minAge: '2020-08-04' }));

    const nextDate = await UtilsModule.nextDates(DATE, PAYLOAD);
    expect(nextDate).toEqual({ minAge: '2020-08-04' });
  });
});

单元测试结果:

 PASS  stackoverflow/62736904/utilsModule.test.js (11.51s)
  62736904
    ✓ testing function (3ms)

----------------|---------|----------|---------|---------|-------------------
File            | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------|---------|----------|---------|---------|-------------------
All files       |      75 |      100 |   33.33 |      75 |                   
 utilsModule.js |      75 |      100 |   33.33 |      75 | 6-7               
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.892s

推荐阅读