【问题标题】:Spy on default exported function with Jest使用 Jest 监视默认导出函数
【发布时间】:2020-09-03 15:15:31
【问题描述】:

我需要测试是否在我正在测试的 addCampus 方法中调用了 logger() 函数,当它抛出错误时。我对开玩笑很陌生,所以我可能会遗漏一些简单的东西

Logger.js

function logger(level, message) {
//logs message to console
//has no explicit return
}

export default logger;

AddCampusList.jsx

import logger from '../../Logger';
addCampus = campus => {
    axios
      .post('/api/campuses/', {
        name: campus.campusName,
        abbreviation: campus.campusAbbreviation,
      })
      .then(response => {
        const { campuses } = this.state;
        campuses.push(response.data);
        this.setState({ campuses });
      })
      .catch(error => {
        this.props.displayError(error);
        logger('ERROR', error);
      });
  };

AddCampusList.test.js

import logger from '../../../src/Logger.js'
...
it('calls displayError() with error', async () => {
      getSpy = jest.spyOn(axios, 'get').mockRejectedValueOnce(error);
      const logger = jest.fn();
      const loggerSpy = jest.spyOn(logger, 'default');
      wrapper = await shallow(<AddCampusList
        displayError={displayError}
        onSelectCampus={onSelectCampus}
        selectedCampus={selectedCampus}
        isMobileViewport={isMobileViewport}
      />);

      expect(displayError).toHaveBeenCalledWith(error);
      expect(loggerSpy).toHaveBeenCalled();
    });

expect(displayError) 工作正常,但expect(loggerSpy) 不正常。 我尝试了几种不同的方法,但这是我最常遇到的错误

 Cannot spy the default property because it is not a function; undefined given instead
> 105 |       const loggerSpy = jest.spyOn(logger, 'default');

【问题讨论】:

    标签: javascript reactjs unit-testing logging jestjs


    【解决方案1】:

    logger 已经是默认导入,所以它不应该有 default 属性。

    窥探它的正确方法是:

    import * as loggerMod from '../../../src/Logger'
    ...
    const loggerSpy = jest.spyOn(loggerMod, 'default');
    

    这可能不起作用,因为 ES 模块是只读的,并且是否强制执行取决于设置。

    更正确的方法是在模块模拟中这样做:

    import logger from '../../../src/Logger'
    
    jest.mock('../../../src/Logger.js', () => {
      const loggerMod = jest.requireActual('../../../src/Logger');
    
      return {
        ...loggerMod,
        __esModule: true,
        default: jest.fn(loggerMod.default)
      };
    });
    
    ...
    
    expect(logger).toHaveBeenCalled();
    

    大多数时候,最好模拟一个具有潜在不良副作用的函数,而不是对其进行监视,这要简单得多,尤其是对于仅具有默认导出的模块:

    jest.mock('../../../src/Logger', () => jest.fn());
    

    【讨论】:

    • 感谢您的回复。您的第二个解决方案效果很好!非常感谢
    猜你喜欢
    • 2019-06-12
    • 2015-12-29
    • 2016-03-10
    • 2021-04-12
    • 1970-01-01
    • 2020-12-30
    • 1970-01-01
    • 2020-02-03
    • 2018-11-24
    相关资源
    最近更新 更多