2015-04-18 7 views
27

Ich verwende moment.js, um die meisten meiner Datumslogik in einer Hilfsdatei für meine React-Komponenten zu machen, aber ich konnte nicht herausfinden, wie man ein Datum in Jest a la sinon.useFakeTimers() vortäuscht.Wie stelle ich ein Mock Date in Jest ein?

Die Jest Docs sprechen nur über Timer-Funktionen wie setTimeout, setInveral etc aber helfen nicht bei der Festlegung eines Datums und dann überprüfen, dass meine Date-Funktionen tun, was sie tun sollen. Hier

ist einige meiner JS-Datei:

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; 

und hier ist das, was ich aufgebaut habe mit 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); 
    }); 

    }); 

}); 

Nun sind diese Tests bestehen, weil ich zur Zeit bin mit und meine Funktionen nutzen Moment, aber es scheint ein bisschen instabil und ich möchte das Datum auf eine feste Zeit für die Tests setzen.

Irgendeine Idee, wie das erreicht werden könnte?

Antwort

21

MockDate können im Scherz Tests verwendet werden, zu ändern, was new Date() kehrt:

var MockDate = require('mockdate'); 
// I use a timestamp to make sure the date stays fixed to the ms 
MockDate.set(1434319925275); 
// test code here 
// reset to native Date() 
MockDate.reset(); 
43

Da momentjs Date intern verwendet, können Sie einfach die Date.now Funktion überschreiben, immer den gleichen Moment zurück.

Date.now = jest.fn(() => 1487076708000) //14.02.2017 
+8

Hier ist ein wenig schönere Verfahren zur Bestimmung der tatsächlichen Datum einstellen, die zurückgegeben werden: 'Date.now = jest.fn (() => neues Datum (Date.UTC (2017, 0, 1)). valueOf()); ' – developering

9

jest.spyOn Arbeiten zur Verriegelung Zeit:

let dateNowSpy; 

beforeAll(() => { 
    // Lock Time 
    dateNowSpy = jest.spyOn(Date, 'now').mockImplementation(() => 1487076708000); 
}); 

afterAll(() => { 
    // Unlock Time 
    dateNowSpy.mockReset(); 
    dateNowSpy.mockRestore(); 
}); 
+1

Tolle Lösung; keine Abhängigkeiten und das Zurücksetzen ist möglich, um die Anwendung auf einen einzelnen Test zu erleichtern. –

0

die Antwort basierend Alle nur auf dem Gespött Date.now() werden, da einige Pakete nicht überall funktionieren (zB moment.js) verwenden new Date() statt.

In diesem Zusammenhang ist die Antwort basierend auf MockDate ich denke das einzig richtig. Wenn Sie nicht über ein externes Paket verwenden möchten, können Sie direkt in Ihrem beforeAll schreiben:

const DATE_TO_USE = new Date('2017-02-02T12:54:59.218Z'); 
    // eslint-disable-next-line no-underscore-dangle 
    const _Date = Date; 
    const MockDate = (...args) => { 
    switch (args.length) { 
     case 0: 
     return DATE_TO_USE; 
     default: 
     return new _Date(...args); 
    } 
    }; 
    MockDate.UTC = _Date.UTC; 
    MockDate.now =() => DATE_TO_USE.getTime(); 
    MockDate.parse = _Date.parse; 
    MockDate.toString = _Date.toString; 
    MockDate.prototype = _Date.prototype; 
    global.Date = MockDate; 
Verwandte Themen