How to Mock JSX in React
Mocking JSX components in React is a crucial technique for unit testing, allowing you to isolate the component under test by replacing its child components with simplified, predictable alternatives. This article covers the most effective ways to mock JSX components using popular testing frameworks like Jest and Vitest, ensuring your tests remain fast, reliable, and focused.
Why Mock JSX Components?
When unit testing a parent component, you often want to avoid rendering its complex child components. Mocking child JSX components helps to: * Isolate dependencies: Test the parent component’s logic without worrying about bugs in its children. * Improve performance: Avoid rendering heavy third-party libraries or complex UI trees. * Simplify assertions: Easily verify that the child component was called with the correct props.
Method 1:
Mocking ES Modules with jest.mock or
vi.mock
The most common way to mock a JSX component imported from another file is to mock the module. This replaces the actual component with a dummy functional component.
Imagine you have a Parent component that renders a
Child component:
// Child.jsx
export default function Child({ message }) {
return <div>{message}</div>;
}In your test file, you can mock the Child component like
this:
import { render, screen } from '@testing-library/react';
import Parent from './Parent';
// Mock the child component module
jest.mock('./Child', () => {
return function DummyChild({ message }) {
return <div data-testid="mock-child">{message}</div>;
};
});
test('renders parent with mocked child', () => {
render(<Parent />);
const mockChild = screen.getByTestId('mock-child');
expect(mockChild).toBeInTheDocument();
});Note: If you are using Vitest, simply replace
jest.mock with vi.mock.
Method 2: Mocking Third-Party Dependency Components
If your JSX component relies on a third-party library (like a charting library or a complex icon pack), you can mock the entire library.
Here is how to mock a component from a library like
react-router-dom:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
Link: ({ children, to }) => <a href={to}>{children}</a>,
}));Using jest.requireActual ensures you only override the
JSX components you need to mock, while keeping other utility functions
(like hooks) intact.
Method 3: Spying on Props
Sometimes you need to verify that a mocked JSX component received the
correct props from the parent. You can achieve this by passing a Jest
mock function (jest.fn()) as the implementation.
import { render } from '@testing-library/react';
import Parent from './Parent';
import Child from './Child';
jest.mock('./Child', () => jest.fn(() => <div data-testid="mock-child" />));
test('passes correct props to the child', () => {
render(<Parent user="Alice" />);
// Assert that the mock was called with specific props
expect(Child).toHaveBeenCalledWith(
expect.objectContaining({ name: 'Alice' }),
expect.anything()
);
});Using these patterns allows you to cleanly isolate your components, resulting in faster execution times and highly reliable test suites.