从 Jest 中的桶文件延迟加载导入

Lazy-load imports from barrel file in Jest

我正在使用 React 并且有一个像这样的文件树:

src/
  common/
    common-comp1/
      common-comp1.js
      common-comp1.test.js
      index.js
    common-comp2/
      common-comp2.js
      common-comp2.test.js
      index.js
    index.js
  app/
    app-comp1/
      app-comp1.js
      app-comp1.test.js
      index.js
    app-comp2/
      app-comp2.js
      app-comp2.test.js
      index.js
    index.js

所有 index.js 文件都是 export * from '...'; 的桶形文件。我设置了路径别名,这样我就可以 import CommonComp1 from 'common'; in src/app/app-comp1/app-comp1.js.

不幸的是,这个 loads/transforms 来自 src/common/common-comp2/* 的代码也是如此,尽管 app-comp1.js 没有导入它。这在我使用 webpack 构建应用程序时很好,因为无论如何我都需要导入和转换所有内容。

但是,对于包含大约 350 个组件的测试,这使得 运行单个测试套件在启动时非常慢。我只想 import/transform 运行 测试所需的文件。有没有办法延迟加载每个 export/import?我想也许我可以通过模拟我的桶文件并导出一个 Proxy 来做到这一点,当它们被直接导入时,只有 requires/memoizes 个组件,通过调用 jest.requireActual()。我开始这样做,但后来意识到我必须解析整个文件树以获取导入和导出名称,这听起来很乏味。 (至少我认为我必须这样做。)

我想我也可以尝试代理 require() 本身(几周前我尝试过这个不同的问题),但是 iirc,它是一个常量或声明 non-configurable/non-writable.

想法?

您可以在测试中使用模块工厂参数模拟桶文件,并仅设置您想要的导出。

如果 common-comp1.js 导出为默认值,请这样做:

应用-comp1.test.js:

jest.mock('common',()=>{
  const CommonComp1 = jest.requireActual('common/common-comp1').default;
  return {__esModule: true, CommonComp1}
})

如果 common-comp1.js 导出被命名,那么这样做:

应用-comp1.test.js:

jest.mock('common',()=>{
  const allNamedExports = jest.requireActual('common/common-comp1');
  return {__esModule: true, ...allNamedExports}
})

对于更自动化的版本,您可以让脚本生成 __mocks__/index.js 个文件。

该脚本将遍历每个 index.js 文件导入它,获取导出的名称并将它们放入 module.exports 对象 getter.

像这样:

__mocks__/common.js:

module.exports={
    get CommonComp1() { 
        return jest.requireActual('../common/common-comp1').CommonComp1;
    }
    get OtherExportFromCommonComp1() { 
        return jest.requireActual('../common/common-comp1').OtherExportFromCommonComp1;
    }
    get CommonComp2() { 
        return jest.requireActual('../common/common-comp2').CommonComp2;
    }
}