【问题标题】:how to unit test uncaughtException and unhandledRejection in Nodejs using Jest如何使用 Jest 在 Nodejs 中对 uncaughtException 和 unhandledRejection 进行单元测试
【发布时间】:2020-12-21 00:53:28
【问题描述】:

我已经建立了一个这样的错误处理程序:

const logger = require('./logger');

module.exports = () => {
  process.on('uncaughtException', (err) => {
    logger.error(err.message, err);
    process.exit(1);
  });

  process.on('unhandledRejection', (err) => {
    throw err;
  });
};

现在我想对此进行单元测试,主要是第一个事件监听器。我当前的测试如下所示:

const logger = require('../../utils/logger');
require('../../utils/unhandledErrors')();

describe('Uncaught Exceptions', () => {
  it('should log the exception and exit the process', () => {
    process.exit = jest.fn();
    logger.error = jest.fn();
    jest.fn(() => {
      throw new Error('fake error');
    })();

    expect(logger.error).toBeCalledTimes(1);
    expect(process.exit).toBeCalledTimes(1);
    expect(process.exit).toBeCalledWith(1);
  });
});

上面的代码在抛出新的错误行时失败,尽管有 --verbose 标志,但没有任何有用的信息被 jest 记录到控制台。
有关如何对此类模块进行单元测试的任何建议?我浏览了下面的链接,但一无所获。
How to test a unhandledRejection / uncaughtException handler with jest

【问题讨论】:

    标签: node.js unit-testing jestjs


    【解决方案1】:

    我的测试策略是使用jest.spyOn(object, methodName) 将间谍安装到process.on()process.exit()console.error 方法上。这样做之后,这些方法就没有副作用了。然后,您可以在隔离环境中测试您的代码逻辑。

    例如

    unhandledErrors.js:

    module.exports = () => {
      process.on('uncaughtException', (err) => {
        console.error(err.message);
        process.exit(1);
      });
    
      process.on('unhandledRejection', (err) => {
        throw err;
      });
    };
    

    unhandledErrors.test.js:

    const unhandledErrors = require('./unhandledErrors');
    
    describe('65386298', () => {
      afterEach(() => {
        jest.restoreAllMocks();
      });
      it('should handle uncaughtException', () => {
        const mError = new Error('Server internal error');
        jest.spyOn(process, 'on').mockImplementation((event, handler) => {
          if (event === 'uncaughtException') {
            handler(mError);
          }
        });
        jest.spyOn(console, 'error').mockReturnValueOnce();
        jest.spyOn(process, 'exit').mockReturnValueOnce();
        unhandledErrors();
        expect(process.on).toBeCalledWith('uncaughtException', expect.any(Function));
        expect(process.exit).toBeCalledWith(1);
        expect(console.error).toBeCalledWith('Server internal error');
      });
    
      it('should handle unhandledRejection', () => {
        const mError = new Error('dead lock');
        jest.spyOn(process, 'on').mockImplementation((event, handler) => {
          if (event === 'unhandledRejection') {
            handler(mError);
          }
        });
        expect(() => unhandledErrors()).toThrowError('dead lock');
        expect(process.on).toBeCalledWith('unhandledRejection', expect.any(Function));
      });
    });
    

    单元测试结果:

     PASS  examples/65386298/unhandledErrors.test.js
      65386298
        ✓ should handle uncaughtException (3 ms)
        ✓ should handle unhandledRejection (1 ms)
    
    --------------------|---------|----------|---------|---------|-------------------
    File                | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    --------------------|---------|----------|---------|---------|-------------------
    All files           |     100 |      100 |     100 |     100 |                   
     unhandledErrors.js |     100 |      100 |     100 |     100 |                   
    --------------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        5.201 s
    

    【讨论】:

      猜你喜欢
      • 2020-06-14
      • 1970-01-01
      • 2021-08-08
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 2020-11-12
      • 2020-12-28
      相关资源
      最近更新 更多