Reputation: 1064
I'm filtering some messages with the following code:
const consoleLog = console.log;
console.log = (...args) => {
if (args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]')) {
consoleLog.apply(console, args);
}
};
How can I test the console output of this function? Normally, I'd just mock console.log
, but in this case it's overwritten by the code above, so I can't do that.
Upvotes: 2
Views: 1179
Reputation: 7017
Or don't mess with the original console.log
at all.
const consoleLog = (...args) => {
if (args.length === 0 || typeof args[0] !== 'string' || !args[0].includes('[HMR]')) {
console.log.apply(console, args);
}
};
Then utilize consoleLog
exclusively in your application code.
Benefit of this indirection:
console.log
at all.console.log
to e.g. a 3rd-party logging framework later, you don't have to adjust all your logging code.However, if you are intentionally configuring code beyond your control (3rd-party) that uses console.log
, this of course will not work for that case.
With this approach, for unit testing, spy on console.log
(which was never modified) as recommended in the answer from estus.
Upvotes: 1
Reputation: 222319
It's generally not a good practice to monkey-patch global APIs. And it's better to expose original function just in case, at least for testing purposes.
It would be easier to test it if it were more flexible, e.g. patched code could be controlled with environment variables, in case there's a need to fall back to original behaviour:
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);
}
};
In this case console._logOriginal
can be spied.
Otherwise original console.log
should be backed up before this module is evaluated, it shouldn't be imported before that:
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;
});
Upvotes: 0