Jest mock 不允许在单个测试中解析内部函数

Jest mock not allowing inner function to be resolved in individual test

我正在我的 functions/send.js 模块中测试一个名为 myCloudFn 的云函数。我的测试在 functions/test/send.test.js:

// send.js
const { getCompareDate } = require('../utils.js');

async function myCloudFn(myTestDate) {
  const compareDate = await getCompareDate(argToTest);
  const isOlder = myTestDate < compareDate;
  return isOlder ? 'older' : 'newer';
}

module.exports = { myCloudFn };
// send.test.js
const send = require('../send.js');

jest.mock('../utils', () => ({
  getCompareDate: jest.fn(() => new Date('2020-01-31')) // default
    .mockResolvedValueOnce(new Date('2020-04-04'))
    .mockResolvedValueOnce(new Date('2020-02-02')),
}));

describe('send.js', () => {
  it('returns date comparison from myCloudFn()', async () => {
    const myTestDate = '2020-03-03';
    const returnValues = ['older', 'newer'];
    const responsePromises = returnValues.map(() => send.myCloudFn(myTestDate));
    const responses = await Promise.all(responsePromises);
    expect(responses[0]).toBe(returnValues[0]);
    expect(responses[1]).toBe(returnValues[1]);
  });
});

当我以这种方式模拟 getCompareDate 时,测试正常运行并按预期通过,但为了灵活性,我宁愿在我的测试中为 getCompareDate 而不是 [=27] 提供自定义输入值=].这是我尝试过的:

const mockGetCompareDate = jest.fn();

jest.mock('../utils', () => ({
  getCompareDate: mockGetCompareDate,
}));
  it('returns date comparison from myCloudFn()', async () => {
    mockGetCompareDate
      .mockResolvedValueOnce(new Date('2020-04-04'))
      .mockResolvedValueOnce(new Date('2020-02-02'));

    const myTestDate = '2020-03-03';
    const returnValues = ['older', 'newer'];
    const responsePromises = returnValues.map(() => send.myCloudFn(myTestDate));
    const responses = await Promise.all(responsePromises);
    expect(responses[0]).toBe(returnValues[0]);
    expect(responses[1]).toBe(returnValues[1]);
  });

但是,此方法不起作用并抛出错误: ReferenceError: Cannot access 'mockGetCompareDate' before initialization 我已将此方法与解决方案 中所述的其他测试一起使用,但我在这里没有看到类似的结果。我错过了什么?

Jest 正在将模拟函数提升到模块顶部,因此抛出此错误。模拟应该在 运行 测试之前使用。 Further reading.

试试这个:

const { getCompareDate } = require('../utils.js');

const mockGetCompareDate = jest.fn(() => new Date('2020-01-31'));

jest.mock('../utils.js', () => ({
  __esModule: true,
  getCompareDate: jest.fn(),
  default: jest.fn()
}));

beforeAll(() => {
  getCompareDate.mockImplementation(mockGetCompareDate);
});

在初始化 mock 函数时,要像以前一样提供自定义值。 Source

像这样:

const mockGetCompareDate = jest.fn()
      .mockResolvedValueOnce(new Date('2020-04-04'))
      .mockResolvedValueOnce(new Date('2020-02-02'));

或者像之前在测试中做的那样。 Source

像这样:

it('returns date comparison from myCloudFn()', async () => {
    mockGetCompareDate
      .mockResolvedValueOnce(new Date('2020-04-04'))
      .mockResolvedValueOnce(new Date('2020-02-02'));