当同时使用 Jest 和 ESM 时,如何避免混合静态和动态导入?

Jos*_*eph 6 javascript mocking jestjs es6-modules

最近我不得不将我的项目迁移到ESM,主要是因为我使用的许多依赖项不再与CommonJS兼容。

通过这样做,我遇到了很多麻烦,但我一步步解决了。然而,我现在用Jest进行测试的方式比以前更糟糕。

这就是我之前使用spyOn图书馆的方式:

it('stringFormatMatchValidatorFactory return the correct result', async () => {
  const spiedValidate = jest.spyOn(ValidatorHelper, 'validateStringFormat');
  const testDataFunctionMatch = Validator.stringFormatMatchValidatorFactory({
    toMatch: true,
    pattern: StringFormatEnum.ALL,
  });
});
Run Code Online (Sandbox Code Playgroud)

这就是我现在必须这样做的:

import { importMockedEsm } from '@nestjs-yalc/jest/esm.helper.js';
import { DeepMocked } from '@golevelup/ts-jest';

const ValidatorHelper = (await importMockedEsm(
  '../validator.helper.js',
  import.meta,
)) as DeepMocked<typeof import('../validator.helper.js')>;

const Validator = await import('../validator.decorator.js');

// [...]


it('stringFormatMatchValidatorFactory return the correct result', async () => {
  const spiedValidate = jest.spyOn(ValidatorHelper, 'validateStringFormat');
  const testDataFunctionMatch = Validator.stringFormatMatchValidatorFactory({
    toMatch: true,
    pattern: StringFormatEnum.ALL,
  });
});
Run Code Online (Sandbox Code Playgroud)

importMockedEsm我必须在项目中设置的自定义函数在哪里,并且它不完全支持部分模拟。

正如您所看到的,静态导入和动态导入混合在一起,这使得 Visual Studio Code IDE 在自动完成和类型检查方面的工作更加糟糕。

发生这种情况是因为 ESM 模块被视为“冻结”模块,这意味着spyOn无法再模拟其功能,但使用新的 Jest 进行模拟unstable_mockModule意味着我们应该对需要使用模拟模块的所有依赖项使用动态导入。

参考:

将我的项目保留在 CommonJS 下并降级其他依赖项实际上是不可能的(我已经读到人们到处建议它)。许多软件包正在放弃对 CommonJS 的支持。

我已经四处寻找替代解决方案,但显然 JavaScript 世界正在进行这种转换,而 Jest 和许多其他工具还没有准备好。

我想使用以下语法来避免它:

const ValidatorHelper = (await importMockedEsm(
  '../validator.helper.js',
  import.meta,
)) as DeepMocked<typeof import('../validator.helper.js')>;
Run Code Online (Sandbox Code Playgroud)

并且没有静态和动态导入。

有没有办法避免每次我需要模拟/监视模块函数时都需要上面的语法?有没有办法让 Visual Studio Code 在任何地方(在__tests__文件夹中,对于.spec文件)使用动态导入?