Jest setSystemTime 不适用于全局范围

问题描述 投票:0回答:3

我正在尝试测试一个简单的减速器,其日期属性设置为今天。

const today = new Date();

export const initialState = {
  today
};

console.log(new Date().toDateString()); // <--- real date

export default function globalReducer(state = initialState, action) {
  console.log(new Date().toDateString()); // <--- mocked date
  switch (action.type) {
    default:
      return state;
  }
}

我的基本测试

import globalReducer from "./reducer";

describe("Global reducer", () => {
  beforeAll(() => {
    jest.useFakeTimers("modern");
    jest.setSystemTime(new Date("2021-02-18"));
  });

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

  it("should return the mocked date", () => {
    expect(globalReducer(undefined, {}).today).toEqual(new Date('2021-02-18'));
  });
});

我注意到模拟只能在reducer代码中工作,但今天在其全局范围内总是返回真实日期而不是模拟日期。

如果我在测试设置文件中调用

setSystemTime
,则
today
会被正确模拟。

我在这里遗漏了什么吗?仅针对特定测试在全局范围内模拟日期的方法是什么?

如果您想查看的话,这里有一个测试仓库 https://github.com/dariospadoni/jestFakeTimersMock

reactjs unit-testing jestjs mocking react-testing-library
3个回答
7
投票

发生这种情况的原因是因为在调用

Date
之前,在
recucer.js
中实例化了
setSystemTime

以下是如何避免这种情况的示例:

beforeAll(() => {
  jest.setSystemTime(new Date("2021-02-18"));
});

describe("Global reducer", () => {
  let globalReducer;

  beforeAll(() => {
    globalReducer = require("./reducer").default;
  });

  it("should return the mocked date", () => {
    expect(globalReducer(undefined, {}).today).toEqual(new Date("2021-02-18"));
  });
});

这里,一旦需要

Date
reducer.js
对象就会被实例化,这将在调用
setSystemTime
之后


0
投票

就我而言,它在

fakeAsync
函数中不起作用。当我控制台日志时,我一直看到真实的日期。从
fakeAsync
中删除测试,我可以看到模拟的日期。


0
投票

您可以通过使用返回对象

initialState
的函数来解决此问题,例如
getInitialState
。这样,
Date
构造函数仅在调用函数时实例化,而不是在文件导入时实例化。此外,您还需要将
today
常量移至函数内部。

© www.soinside.com 2019 - 2024. All rights reserved.