_new Date
_に依存して日付オブジェクトを作成し、それを操作するメソッドがあります。私は操作が期待どおりに機能することをテストしているので、返された日付を期待された日付と比較する必要があります。そのためには、テストでもテストされるメソッドでも_new Date
_が同じ値を返すことを確認する必要があります。どうやってやるの?
コンストラクター関数の戻り値を実際にモックする方法はありますか?
日付オブジェクトを提供し、モックできる関数で必要となるモジュールを作成できます。しかし、それは私のコードでは不必要な抽象化のようです。
テストする関数の例...
_module.exports = {
sameTimeTomorrow: function(){
var dt = new Date();
dt.setDate(dt + 1);
return dt;
}
};
_
new Date()
の戻り値をモックするにはどうすればよいですか?
ジャスミンのspyOn(jestはジャスミン上に構築されています)を使用して、次のようにgetDateの日付のプロトタイプをモックできます。
spyOn(Date.prototype, 'setDate').and.returnValue(DATE_TO_TEST_WITH);
SpyOnは、それ自体が終了した後もクリーンアップし、テストの範囲でのみ持続します。
以下のようにjest.spyOn
を使用して、new Date()のようなコンストラクターをモックできます。
test('mocks a constructor like new Date()', () => {
console.log('Normal: ', new Date().getTime())
const mockDate = new Date(1466424490000)
const spy = jest
.spyOn(global, 'Date')
.mockImplementation(() => mockDate)
console.log('Mocked: ', new Date().getTime())
spy.mockRestore()
console.log('Restored: ', new Date().getTime())
})
出力は次のようになります。
Normal: 1566424897579
Mocked: 1466424490000
Restored: 1566424897608
指定された日付値で構築されたDateオブジェクトを返すモック関数を使用して、Dateコンストラクターをオーバーライドできます。
var yourModule = require('./yourModule')
test('Mock Date', () => {
const mockedDate = new Date(2017, 11, 10)
const originalDate = Date
global.Date = jest.fn(() => mockedDate)
global.Date.setDate = originalDate.setDate
expect(yourModule.sameTimeTomorrow().getDate()).toEqual(11)
})
ここで例をテストできます: https://repl.it/@miluoshi5/jest-mock-date
Dateコンストラクタを、常にハードコードされた日付を返すものに置き換え、完了したら通常に戻すことができます。
var _Date = null;
function replaceDate() {
if (_Date) {
return
};
_Date = Date;
Object.getOwnPropertyNames(Date).forEach(function(name) {
_Date[name] = Date[name]
});
// set Date ctor to always return same date
Date = function() { return new _Date('2000-01-01T00:00:00.000Z') }
Object.getOwnPropertyNames(_Date).forEach(function(name) {
Date[name] = _Date[name]
});
}
function repairDate() {
if (_Date === null) {
return;
}
Date = _Date;
Object.getOwnPropertyNames(_Date).forEach(function(name) {
Date[name] = _Date[name]
});
_Date = null;
}
// test that two dates created at different times return the same timestamp
var t0 = new Date();
// create another one 100ms later
setTimeout(function() {
var t1 = new Date();
console.log(t0.getTime(), t1.getTime(), t0.getTime() === t1.getTime());
// put things back to normal when done
repairDate();
}, 100);
私はちょうどjestテストを書いて、new Date()
をglobal.Date = () => now
でスタブすることができました
date-faker を使用して、新しいDate()またはDate.now()が返すものを模擬できます。
import { dateFaker } from 'date-faker'; // var { dateFaker } = require('date-faker');
// will return tomorrow, shift by one unit
dateFaker.add(1, 'day');
// shift by several units
dateFaker.add({ year: 1, month: -2, day: 3 });
// set up specific date, accepts Date or time string
dateFaker.set('2019/01/24');
dateFaker.reset();