【问题标题】:Test module.hot with Jest用 Jest 测试 module.hot
【发布时间】:2017-07-11 14:13:12
【问题描述】:

我正在尝试将具有热模块重新加载设置的模块的覆盖率提高到 100%。

在我的模块中,我有这个:

// app.js
if (module && module.hot) module.hot.accept();

在测试文件中我正在尝试这样做

// app.test.js
it('should only call module.hot.accept() if hot is defined', () => {
    const accept = jest.fn();
    global.module = { hot: { accept } };
    jest.resetModules();
    require('./app');
    expect(accept).toHaveBeenCalled();
  }
);

但是当我在 app.js 中注销模块时,它会显示需要的东西,但不包含测试设置的热方法。

【问题讨论】:

  • 我也没有找到答案,但这似乎是可以接受的: /* istanbul ignore if */ 就在 if (module && module.hot... 行

标签: javascript reactjs jestjs


【解决方案1】:

如果您有一个引用模块对象的变量,那么您可以将一个模拟模块对象注入该变量以进行测试。例如,您可以执行以下操作:

// app.js

// ...
  moduleHotAccept(module);
// ...

export function moduleHotAccept(mod) {
  if (mod && mod.hot) {
    mod.hot.accept();
  }
}

可以这样测试:

// app.test.js
import { moduleHotAccept } from './app'

it('should only call hot.accept() if hot is defined', () => {
    const accept = jest.fn();
    const mockModule = { hot: { accept } };
    moduleHotAccept(mockModule);
    expect(accept).toHaveBeenCalled();
  }
);

it('should not throw if module is undefined', () => {
    expect(moduleHotAccept).not.toThrow();
  }
);

it('should not throw if module.hot is undefined', () => {
    expect(
      () => moduleHotAccept({notHot: -273})
    ).not.toThrow();
  }
);

【讨论】:

    【解决方案2】:

    我也需要它,但无法从外部传递它。

    我的解决方案是使用一个笑话"transform",它允许我稍微修改使用module.hot 的文件的代码。

    所以为了设置它你需要添加:

    // package.json
    
    "transform": {
      "file-to-transform.js": "<rootDir>/preprocessor.js"
    //-------^ can be .* to catch all
    //------------------------------------^ this is a path to the transformer
    },
    

    preprocessor.js内,

    // preprocessor.js
    
    module.exports = {
      process(src, path) {
        if( path.includes(... the path of the file that uses module.hot)) {
          return src.replace('module.hot', 'global.module.hot');
        }
    
        return src;
      },
    };
    
    

    该转换器会将module.hot 替换为global.module.hot,这意味着您可以像这样在测试中控制它的值:

    // some-test.spec.js
    
    global.module = {
      hot: {
        accept: jest.fn,
      },
    };
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2018-07-26
      • 2020-11-24
      • 2018-06-10
      • 2020-11-06
      • 2020-04-21
      • 1970-01-01
      • 2020-12-15
      • 2017-11-23
      • 2021-11-02
      相关资源
      最近更新 更多