I have written three Jest unit tests and I am mocking a function. This mock is used for two unit tests but my third one fails since it needs to access the real code. If I comment out the mock, then the first two tests fail and third one passes. I tried using beforeAll and beforeEach methods where I disable the mock only for the third test but haven’t had any success. I’d appreciate any help!
ReactErrorBoundary.tsx:
import { render, act, fireEvent } from '@testing-library/react';
import ReactErrorBoundary from '../../components/ReactErrorBoundary';
import { ErrorBoundary } from 'react-error-boundary';
import { logger } from '../../services/logService';
jest.mock('../../services/logService', () => ({
logger: jest.fn(),
}));
jest.mock('react-error-boundary', () => {
const ErrorPage = require('../../components/ErrorPage').default;
return {
...jest.requireActual('react-error-boundary'),
ErrorBoundary: jest.fn(({ onError, onReset, FallbackComponent }) => {
onError && onError(new Error());
onReset && onReset();
return {
FallbackComponent: ErrorPage,
};
}),
};
});
describe('ReactErrorBoundary with mocked ErrorBoundary', () => {
beforeAll(() => {
jest.mock('react-error-boundary', () => {
const ErrorPage = require('../../components/ErrorPage').default;
return {
...jest.requireActual('react-error-boundary'),
ErrorBoundary: jest.fn(({ onError, onReset, FallbackComponent }) => {
onError && onError(new Error());
onReset && onReset();
return {
FallbackComponent: ErrorPage,
};
}),
};
});
});
test('renders ErrorBoundary with ErrorPage as FallbackComponent', () => {
render(<ReactErrorBoundary />);
expect(ErrorBoundary).toHaveBeenCalledWith({
FallbackComponent: expect.any(Function),
onError: expect.any(Function),
onReset: expect.any(Function),
children: undefined,
}, {});
});
test('passes children to ErrorBoundary', () => {
const children = <div>Hello World</div>;
render(<ReactErrorBoundary>{children}</ReactErrorBoundary>);
expect(ErrorBoundary).toHaveBeenCalledWith({
FallbackComponent: expect.any(Function),
onError: expect.any(Function),
onReset: expect.any(Function),
children: <div>Hello World</div>,
}, {});
});
});
describe('ReactErrorBoundary without mocked ErrorBoundary', () => {
beforeAll(() => {
jest.unmock('react-error-boundary');
});
test('logs error message when onError is triggered', () => {
const spy = jest.spyOn(console, 'log').mockImplementation();
render(
<ReactErrorBoundary>
<ChildComponentWithError />
</ReactErrorBoundary>
);
expect(spy).toBeCalledTimes(1);
expect(spy).toHaveBeenCalledWith('Error caught!');
expect(logger).toBeCalledTimes(1);
expect(logger).toHaveBeenCalledWith(expect.any(Error));
spy.mockRestore();
});
});
const ChildComponentWithError = () => {
throw new Error('Test Error');
};