jest.spyOn() 对导入的模块有效,但对同一模块的导入函数失败

问题描述 投票:0回答:1
// my-func.test.js
import { jest } from '@jest/globals';
import { myFunc } from './my-func.js';
import fs from 'node:fs';

const mock = jest.fn().mockReturnValue({isDirectory: () => true});
jest.spyOn(fs, 'statSync').mockImplementation(mock);

it('should work', () => {
  expect(myFunc('/test')).toBeTruthy();

  expect(mock).toHaveBeenCalled();
});

此实现测试通过:

// my-func.js
import fs from 'node:fs';
// import { statSync } from 'node:fs';

export function myFunc(dir) {
  const stats = fs.statSync(dir, { throwIfNoEntry: false });
  // const stats = statSync(dir, { throwIfNoEntry: false });
  return stats.isDirectory();
}

但是,如果实现更改为(注意不同的导入机制):

// my-func.js
// import fs from 'node:fs';
import { statSync } from 'node:fs';

export function myFunc(dir) {
  // const stats = fs.statSync(dir, { throwIfNoEntry: false });
  const stats = statSync(dir, { throwIfNoEntry: false });
  return stats.isDirectory();
}

Jest 将会失败:

Cannot read properties of undefined (reading 'isDirectory')
TypeError: Cannot read properties of undefined (reading 'isDirectory')

如何使用

statSync
语法监视或模拟
import { statSync } from 'node:fs';
?还可能吗?

注意测试是在ES模块模式下运行的:

# package.json
{
  "type": "module",
  "scripts": {
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
    ...
  },
  "devDependencies": {
    "@eslint/js": "^9.17.0",
    "@jest/globals": "^29.7.0",
    "globals": "^15.14.0",
    "jest": "^29.7.0",
    ...
  },
  ...
}
javascript node.js jestjs
1个回答
-1
投票

Jest 通过替换或监视对象的属性来工作(例如当 fs 作为整体导入时 fs.statSync)。命名导入的问题是没有可用于模拟的对象或属性

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