node.js - 如何使用 Jest 在 Nodejs 中对 uncaughtException 和 unhandledRejection 进行单元测试
问题描述
我已经建立了一个这样的错误处理程序:
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 没有将有用的信息记录到控制台。
有关如何对此类模块进行单元测试的任何建议?我浏览了下面的链接,但一无所获。
如何用 jest 测试 unhandledRejection / uncaughtException 处理程序
解决方案
我的测试策略是安装 spy和使用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
推荐阅读
- java - 在尝试使复合类方法对另一个包类可见时避免违反 SOLID 原则
- cassandra - 如何在没有分区键的情况下使用 ORDER_BY 搜索记录
- html - IE/Edge 不考虑绝对底部
- javascript - 有没有办法将事件监听器添加到类中?
- ios - UIAlertController 没有立即显示
- spring - 页面加载时的 Spring MVC 表单验证
- h2o - 可以为 h2o.save_model() 设置文件名(而不是简单地使用 model_id 值)?
- javascript - 谷歌地图标记没有显示 javascript
- node.js - Amazon Web Services 上的连接被拒绝
- c# - 了解为什么在 Bot Builder Framework 示例中似乎进行了 3 次翻译:MultiLingualBot