How to hide React-Error-Boundary console errors in jest

432 Views Asked by At

From the react docs on Error Boundaries:

React 16 prints all errors that occurred during rendering to the console in development, even if the application accidentally swallows them.

Due to the above I am getting loads of unnecessary console errors when running my tests. Is it possible to hide these in Jest, without mocking/spying on console.error?

1

There are 1 best solutions below

0
On

Right.. Keeping the test output clean is always a good idea. Without mocking and spying - no idea but this is my version of mocking spying.

In this case there are two steps. One is quite obvious: to filter the console output. In the test initialization file, which is something like this:

"jest": {
"setupFilesAfterEnv": [
  "<rootDir>/jest/setupTests.js"
],

There is my code for errors and warnings filtering.

const warningPatterns = [
    /componentWillReceiveProps/,
    /The `css` function is deprecated/
];

const errorPatterns = [
    /Should be caught by ErrorBoundary/,
]

global.console = {
    ...global.console,
    warn: (...args) => {
        if (warningPatterns.some(pattern => args.some(line => 
            pattern.test(line)))) {
                return;
            }
        originalWarn(...args);
    },
    error: (...args) => {
        const canSkip = args.some(line => {
            return errorPatterns.some(pattern => {
                return pattern.test(line?.message || line);
            });
        });
        if (canSkip) {
            return;
        }
        originalError(...args);
     }
}

And then if you have JSDOM you have to mock the virtual console. I'd prefer to do this in the test cause you might not have too many Boundary tests.

it('should catch Errors', () => {
    const virtualConsole = window._virtualConsole;
    const originalEmit = virtualConsole.emit;
    const emit = jest.spyOn(virtualConsole, 'emit');
    emit.mockImplementation(function (type, error) {
        // you may skip the type check
        if (type === 'jsdomError' && error.detail.message === 'Should be caught by ErrorBoundary') {
            return;
        }
        return originalEmit.call(this, type, error);
    });

    const { getByText } = render(() => throw new Error('Should be caught by ErrorBoundary'));
    expect(getByText('Should be caught by ErrorBoundary').toBeInTheDocument();
    emit.mockRestore();
});