使用Jest测试覆盖console.log

时间:2018-10-12 15:39:38

标签: javascript node.js jestjs

我正在使用以下代码过滤某些消息:

awk '{print (NR==1 ? "LN" : NR-1), $0}' OFS="|" file

如何测试此功能的控制台输出?通常,我只是模拟const consoleLog = console.log; console.log = (...args) => { if (args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]')) { consoleLog.apply(console, args); } }; ,但是在这种情况下,它被上面的代码覆盖,所以我不能这样做。

2 个答案:

答案 0 :(得分:1)

或者根本不要弄乱原始的console.log

const consoleLog = (...args) => {
  if (args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]')) {
    console.log.apply(console, args);
  }
};

然后在您的应用程序代码中专门使用consoleLog

这种间接的好处:

  • 更安全。您根本不会猴子修补原始的console.log
  • 更具前瞻性。如果您从console.log切换到例如第三方日志记录框架以后,您无需调整所有日志记录代码。

但是,如果您有意配置超出使用console.log的控制(第三方)的代码,则在这种情况下当然不起作用。

使用这种方法进行单元测试时,请根据发情答案中的建议监视console.log(从未修改)。

答案 1 :(得分:0)

用猴子修补全局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._logOriginal

否则,在评估此模块之前,应备份原始的console.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;
});