【问题标题】:Mock dynamic require in Node with Jest使用 Jest 在 Node 中模拟动态需求
【发布时间】:2019-09-26 20:30:37
【问题描述】:

鉴于需要从父/引用包的根目录动态加载依赖项的 npm 包,并且该位置直到运行时才知道,它必须执行动态要求:

// config-fetcher.js
const path = require('path');
const getRunningProjectRoot = require('./get-running-project-root');'
module.exports = filename =>
   require(path.resolve(getRunningProjectRoot(), filename));

(不能保证模块会在node_modules 中。它可以被符号链接或全局加载。所以它不能使用静态需求。)

这是从实际代码中简化而来的,因此除非您知道一种相对于正在运行的项目根目录非动态地要求文件的方法,否则必须采用这种方式。

现在,为了测试这一点,我不希望依赖任何实际在磁盘上的文件。然而,Jest 似乎不会让你模拟一个不存在的文件。所以如果我试试这个:

const mockFileContents = {};
jest.mock('/absolute/filename.blah', () => mockFileContents);
// in preparation for wanting to do this:
const result = require('./config-fetcher')('/absolute/filename.blah');
expect(result).toBe(mockFileContents);

然后我收到来自jest-resolve 的错误,文件Resolver.resolveModule 抛出Error: Cannot find module '/absolute/filename.blah'.

我需要测试这个动态需求模块的一些功能,因为它处理一些相对路径与绝对路径的情况,并允许您通过符号指定特殊路径,例如 applicationRoot ,因此模块config-fetcher 代替调用者完成了艰苦的工作。

谁能提供关于如何测试这个模块的指导,或者如何重组这样的动态需求不需要或者它们更容易测试?

【问题讨论】:

    标签: node.js mocking jestjs


    【解决方案1】:

    有人试过测试动态导入吗?下面的示例代码进行测试。如果我不使用动态导入 jest.mock + virtual: true 作品。

    const Routes =  React.lazy(() => import('app2/routes'));
    
    jest.mock('does not exist',
      () => ({
        myFunc: () => 'hello'
      }),
      { virtual: true }
    );
    
    test('mock file that does not exist', () => {
      expect(myFunc()).toBe('hello');  // Failed!
    });
    

    【讨论】:

      【解决方案2】:

      您可以在jest.mock 中将{ virtual: true } 传递为options 来模拟一个不存在的模块:

      const { myFunc } = require('does not exist');
      
      jest.mock('does not exist',
        () => ({
          myFunc: () => 'hello'
        }),
        { virtual: true }
      );
      
      test('mock file that does not exist', () => {
        expect(myFunc()).toBe('hello');  // Success!
      });
      

      详情

      Jest 完全接管了require 系统,用于测试代码。

      它有自己的模块缓存并跟踪模块模拟。

      作为该系统的一部分,Jest 允许您为实际不存在的模块创建模拟。

      您可以将options 作为第三个参数传递给jest.mock。目前唯一的选择是virtual,如果是true,那么Jest只会将调用模块工厂函数的结果添加到模块缓存中,并在被测代码需要时返回。

      【讨论】:

        猜你喜欢
        • 2021-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-09
        • 2021-11-09
        • 2022-11-12
        • 2021-03-14
        • 1970-01-01
        相关资源
        最近更新 更多