25
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

jestで現在時刻を固定化する

Last updated at Posted at 2019-08-14

追記

timer-mocks を使ってください。

afterEach(() => {
  jest.useRealTimers();
});

test('', () => {
  const fixed = new Date('2022-1-1T00:00:00');
  jest.useFakeTimers().setSystemTime(fixed.getTime());
  // ...
});

以下の情報は古いです。


はじめに

時間に依存しているようなAPIの振る舞いを試験するとき、現在時刻を固定化して試験したいことがよくあると思います。
Date.now()new Date() をモックすることで、現在時刻を固定化することができます!!

やり方

Dateの振る舞いを固定することで、moment() の現在時刻も固定化できます。

const moment = require('moment')

describe('モックした現在時刻のテスト', () => {
  let now;
  let spiedDate;
  // setup
  beforeAll(() => {
    const OriginalDate = Date; // 退避
    now = new OriginalDate('2019/8/1 12:00:00');
    // Date.now() と new Date() のみmocking
    Date.now = jest.fn().mockReturnValue(now.valueOf());
    spiedDate = jest.spyOn(global, 'Date').mockImplementation((arg) => {
      if (arg === 0 || arg) {
        return new OriginalDate(arg);
      }
      return now;
    });
  });

  afterAll(() => {
    spiedDate.mockRestore();
  });

  test('現在時刻をYYYY/MM/DDの形式で表示できる', () => {
    const actual = moment().format('YYYY/MM/DD');
    expect(actual).toBe('2019/08/01');
  });

  test('Dateコンストラクタで現在時刻が固定化される', () => {
    const actual = new Date();
    expect(actual.valueOf()).toBe(now.valueOf());
  });

  test('Dateコンストラクタで時刻を指定できる', () => {
    const actual = new Date(0);
    expect(actual.valueOf()).toBe(0);
  });
})

説明

ここで固定したい日付を設定します。
後ほどコンストラクタの振る舞いを書き換えるため、Dateオブジェクトを退避しています。

const OriginalDate = Date; // 退避
now = new OriginalDate('2019/8/1 12:00:00');

Date.now() を固定し、常に同じUnix時刻が返却されるようにしています。

Date.now = jest.fn().mockReturnValue(now.valueOf());

jest.spyOn を利用して、コンストラクタで固定の値を返却するようにします。
arg === 0 の判定は、Unix時間0の時も正しく動作させるためです。

spiedDate = jest.spyOn(global, 'Date').mockImplementation((arg) => {
  if (arg === 0 || arg) {
    return new OriginalDate(arg);
  }
  return now;
});

Date オブジェクトを元に戻します。(global.Date = OriginalDate でも同じ効果)

afterAll(() => {
  spiedDate.mockRestore();
});
25
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?