在 Jest 中模拟导入函数

Mock imported function in Jest

我有一个案例:

test.js

import { today } from "utils/date";
import myFunction from "helpers/myFunction";

it('should work properly', () => {
   jest.mock('utils/date', () => ({
      ...(jest.requireActual('utils/date')),
      today: jest.fn(() => '01-01-2020'),
   }));

   console.log(today()); // still logs current date 14-10-2021, not the mocked date       

   expect(myFunction()).toEqual(today());
});

myFunction.js

import { today } from "utils/date";

export const myFunction = () => today();

today 是 return 今天日期的函数。但出于测试目的,我需要该函数 始终 return 相同的日期 ,例如"01-01-2020".

注意:如您所见,“today”函数在测试中以及在被测试的 (myFunction) 函数中使用,因此它必须 return 与应用程序中各处相同的模拟值.

谢谢

jest.mock() 在测试用例功能范围内被调用。模块导入被提升(内部移动到当前范围的开头)。原始 today 函数是在 jest.mock() 模拟 utils/date 模块之前导入的。

您可以将 jest.mock() 从测试用例功能范围移动到模块范围。 Jest 会自动将 jest.mock 调用提升到模块的顶部(在任何导入之前)。所以当你导入 today 函数时,它已经被模拟了。

参见Using with ES module imports

If you're using ES module imports then you'll normally be inclined to put your import statements at the top of the test file. But often you need to instruct Jest to use a mock before modules use it. For this reason, Jest will automatically hoist jest.mock calls to the top of the module (before any imports).

import { today } from 'utils/date';

jest.mock('utils/date', () => ({
  today: jest.fn(() => '01-01-2020'),
}));

it('should work properly', () => {
  expect(jest.isMockFunction(today)).toBeTruthy();
  expect(today()).toBe('01-01-2020');
});