Я использую moment.js для выполнения большей части моей логики дат во вспомогательном файле для моих компонентов React, но я не смог понять, как имитировать дату в Jest a la sinon.useFakeTimers()
.
Документы Jest говорят только о функциях таймера, таких как setTimeout
и setInterval
т. Д., Но не помогают с установкой даты и последующей проверкой того, что мои функции даты выполняют то, что они должны делать.
Вот некоторые из моих файлов JS:
var moment = require('moment');
var DateHelper = {
DATE_FORMAT: 'MMMM D',
API_DATE_FORMAT: 'YYYY-MM-DD',
formatDate: function(date) {
return date.format(this.DATE_FORMAT);
},
isDateToday: function(date) {
return this.formatDate(date) === this.formatDate(moment());
}
};
module.exports = DateHelper;
и вот что я установил с помощью Jest:
jest.dontMock('../../../dashboard/calendar/date-helper')
.dontMock('moment');
describe('DateHelper', function() {
var DateHelper = require('../../../dashboard/calendar/date-helper'),
moment = require('moment'),
DATE_FORMAT = 'MMMM D';
describe('formatDate', function() {
it('should return the date formatted as DATE_FORMAT', function() {
var unformattedDate = moment('2014-05-12T00:00:00.000Z'),
formattedDate = DateHelper.formatDate(unformattedDate);
expect(formattedDate).toEqual('May 12');
});
});
describe('isDateToday', function() {
it('should return true if the passed in date is today', function() {
var today = moment();
expect(DateHelper.isDateToday(today)).toEqual(true);
});
});
});
Теперь эти тесты проходят, потому что я использую момент, а мои функции используют момент, но он кажется немного нестабильным, и я хотел бы установить дату на фиксированное время для тестов.
Есть идеи, как это можно сделать?
Date
подобные функцииvalueOf()
.Поскольку momentjs используется
Date
внутри, вы можете просто перезаписатьDate.now
функцию, чтобы всегда возвращать один и тот же момент.или
источник
Date.now = jest.fn(() => new Date(Date.UTC(2017, 0, 1)).valueOf());
Date.now = jest.fn(() => +new Date('2017-01-01');
Date.now = jest.fn(() => Date.parse('2017-02-14))
jest.spyOn работает для блокировки времени:
источник
dateNowSpy
переменной, и,mockReset()
согласно jestjs.io/docs/en/mock-function-api.html#mockfnmockrestore, это избыточно . ВafterAll
, вы можете просто сделатьDate.now.mockRestore()
Date.now.mockRestore();
дает свойство 'mockRestore' не существует при ошибке типа '() => number'jest-date-mock - это полный модуль javascript, написанный мной, и он используется для тестирования Date на jest.
Используйте только 3 api для тестовых случаев.
источник
Для тех, кто хочет имитировать методы нового объекта Date, вы можете сделать следующее:
источник
Все ответы, основанные только на имитации
Date.now()
, не будут работать везде, поскольку вместо этогоmoment.js
используются некоторые пакеты (например )new Date()
.В этом контексте ответ, на
MockDate
мой взгляд, является единственно правильным. Если вы не хотите использовать внешний пакет, вы можете написать прямо в своемbeforeAll
:источник
Хочу предложить несколько альтернативных подходов.
Если вам нужна заглушка
format()
(которая может зависеть от языка и часового пояса!)Если вам нужно только заглушить
moment()
:Что касается теста для
isDateToday
функции выше, я считаю самым простым способом было бы не издеватьсяmoment
вообщеисточник
TypeError: moment.mockReturnValue is not a function
jest.mock("moment")
на том же уровне, что и ваши импорта заявления? В противном случае вы можете увидеть это в действии в этом проектеВот как я издевался над своим
Date.now()
методом, чтобы установить год на 2010 для моего тестаисточник
Вот несколько удобочитаемых способов для разных случаев использования. Я предпочитаю использовать шпионов, а не сохранять ссылки на исходные объекты, которые могут быть случайно перезаписаны в другом коде.
Одноразовое издевательство
Несколько тестов
источник
Начиная с Jest 26, этого можно добиться с помощью «современных» поддельных таймеров без необходимости установки каких-либо сторонних модулей: https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers
источник
Я бы хотел использовать ручные макеты, чтобы их можно было использовать во всех тестах.
источник
Цель состоит в том, чтобы имитировать new Date () с фиксированной датой, где бы она ни использовалась во время рендеринга компонента в тестовых целях. Использование библиотек будет накладными расходами, если единственное, что вам нужно, - это имитировать new Date () fn.
Идея состоит в том, чтобы сохранить глобальную дату в переменной temp, имитировать глобальный dae, а затем после использования переназначить temp на глобальную дату.
источник
Я просто хотел вмешаться, потому что не было ответа на этот вопрос, если вы хотите издеваться над
Date
объектом только в определенном наборе.Вы можете смоделировать это, используя методы настройки и разборки для каждого набора, jest docs
Надеюсь это поможет!
источник
Вы можете использовать фейкер даты . Позволяет изменить текущую дату относительно:
источник