Javascript 使用Jest覆盖console.log的测试
我正在使用以下代码筛选一些邮件:Javascript 使用Jest覆盖console.log的测试,javascript,node.js,jestjs,Javascript,Node.js,Jestjs,我正在使用以下代码筛选一些邮件: const consoleLog = console.log; console.log = (...args) => { if (args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]')) { consoleLog.apply(console, args); } }; 如何测试此函数的控制台输出?通常情况下,我只会模拟控制台.log,但在这
const consoleLog = console.log;
console.log = (...args) => {
if (args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]')) {
consoleLog.apply(console, args);
}
};
如何测试此函数的控制台输出?通常情况下,我只会模拟控制台.log,但在这种情况下,它会被上面的代码覆盖,所以我不能这样做。通常,对全局API进行修补不是一个好的做法。为了以防万一,至少出于测试目的,最好公开原始函数 如果它更灵活,测试起来会更容易,例如,可以使用环境变量控制打补丁的代码,以防需要退回到原始行为:
console._logOriginal = console.log;
console.log = (...args) => {
if (
!process.env.NO_HMR_SPAM ||
(args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]'))
) {
console._logOriginal(...args);
}
};
在这种情况下,console.\u logOriginal
可以被监视
否则,应在评估此模块之前备份原始的控制台.log
,在此之前不应导入:
const consoleLogOriginal = console.log;
it('...', async () => {
const consoleLogSpy = jest.spyOn(console, 'log');
await import('moduleThatManglesConsole');
console.log('[HMR]');
expect(consoleLogSpy).not.toHaveBeenCalled();
console.log('');
expect(consoleLogSpy).toHaveBeenCalledWith('');
})
afterEach(() => {
console.log = consoleLogOriginal;
});
或者根本不要弄乱原始的
控制台.log
const consoleLog = (...args) => {
if (args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]')) {
console.log.apply(console, args);
}
};
然后在应用程序代码中专门使用consoleLog
这种间接方式的好处:
- 这样更安全。您根本不会对原始的
进行修补控制台.log
- 这更能证明未来。如果以后从
切换到第三方日志框架,则无需调整所有日志代码console.log
console.log
的超出您控制范围的代码(第三方),这当然不适用于这种情况
使用这种方法,对于单元测试,按照estus的回答中的建议,监视console.log
(从未修改过)