Estou usando o moment.js para fazer a maior parte da minha lógica de data em um arquivo auxiliar para meus componentes React, mas não consegui descobrir como simular um encontro em Jest a la sinon.useFakeTimers()
.
Os documentos do Jest falam apenas sobre funções de cronômetro como setTimeout
,setInterval
etc. mas não ajudam a definir uma data e, em seguida, verificar se minhas funções de data fazem o que devem fazer.
Aqui está um pouco do meu arquivo 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;
e aqui está o que configurei usando o 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);
});
});
});
Agora esses testes passam porque estou usando momento e minhas funções usam momento, mas parece um pouco instável e gostaria de definir a data para um horário fixo para os testes.
Alguma ideia de como isso pode ser feito?
Date
likevalueOf()
.Como o momentjs usa
Date
internamente, você pode simplesmente substituir aDate.now
função para sempre retornar o mesmo momento.ou
fonte
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 funciona para bloquear o tempo:
fonte
dateNowSpy
variável emockReset()
é redundante de acordo com jestjs.io/docs/en/mock-function-api.html#mockfnmockrestore . NoafterAll
, você pode simplesmente fazerDate.now.mockRestore()
Date.now.mockRestore();
fornece uma propriedade 'mockRestore' não existe no erro de tipo '() => número'jest-date-mock é um módulo javascript completo escrito por mim, e é usado para testar Date em jest.
Use apenas 3 api para casos de teste.
fonte
Para aqueles que desejam simular métodos em um novo objeto Date, você pode fazer o seguinte:
fonte
Todas as respostas baseadas apenas no mock de
Date.now()
não funcionarão em todos os lugares, pois alguns pacotes (por exemplomoment.js
) usamnew Date()
.Neste contexto, a resposta baseada em
MockDate
acho que é a única verdadeiramente correta. Se não quiser usar um pacote externo, você pode escrever diretamente embeforeAll
:fonte
Eu gostaria de oferecer algumas abordagens alternativas.
Se você precisar fazer um stub
format()
(que pode depender da localidade e do fuso horário!)Se você só precisa de stub
moment()
:Em relação ao teste para a
isDateToday
função acima, acredito que a maneira mais simples seria não zombar demoment
nadafonte
TypeError: moment.mockReturnValue is not a function
jest.mock("moment")
no mesmo nível que suas declarações de importação? Caso contrário, você é bem-vindo para vê-lo em ação neste projetoÉ assim que eu zombei do meu
Date.now()
método para definir o ano de 2010 para o meu testefonte
Aqui estão algumas maneiras legíveis para diferentes casos de uso. Eu prefiro usar espiões em vez de salvar referências aos objetos originais, que podem ser substituídos acidentalmente em algum outro código.
Zombaria única
Alguns testes
fonte
A partir de Jest 26, isso pode ser alcançado usando temporizadores falsos "modernos" sem a necessidade de instalar quaisquer módulos de terceiros: https://jestjs.io/blog/2020/05/05/jest-26#new-fake-timers
fonte
Eu gostaria de usar Mocks manuais, para que possa ser usado em todos os testes.
fonte
O objetivo é simular new Date () com uma data fixa onde quer que seja usado durante a renderização do componente para fins de teste. Usar bibliotecas será uma sobrecarga se a única coisa que você quiser é simular new Date () fn.
A ideia é armazenar a data global em uma variável temporária, simular o dae global e, depois do uso, reatribuir temp para a data global.
fonte
Eu só queria gritar aqui, já que nenhuma resposta abordou o problema se você quiser zombar do
Date
objeto em apenas um conjunto específico.Você pode simular usando os métodos de configuração e desmontagem para cada suíte, jest docs
Espero que isto ajude!
fonte
Você pode usar data-faker . Permite que você altere a data atual relativamente:
fonte