How to Mock Functional Components in React
Mocking React functional components is a crucial technique in unit testing to isolate the component under test and prevent external dependencies or complex child components from affecting your test results. This article provides a straightforward guide on how to mock functional components in React using Jest and React Testing Library, covering both default and named exports with practical, easy-to-follow code examples.
Why Mock Functional Components?
When unit testing a parent component, you often want to verify its behavior without rendering its children. Mocking child components helps you: * Isolate tests: Focus purely on the parent component’s logic, state, and props. * Improve performance: Avoid rendering heavy or deeply nested child components. * Simplify assertions: Replace complex components with simple HTML placeholders that are easy to query.
Mocking Default Exports
If the functional component you want to mock is exported as a default
export, you can use jest.mock() to replace the module path
with a simplified dummy component.
Consider a parent component that imports a child component:
// ChildComponent.js
export default function ChildComponent({ message }) {
return <div>Real Child Component: {message}</div>;
}To mock this child component in your parent component’s test file, declare the mock at the top of your file:
import { render, screen } from '@testing-library/react';
import ParentComponent from './ParentComponent';
// Mock the child component
jest.mock('./ChildComponent', () => {
return function MockChildComponent({ message }) {
return <div data-testid="mock-child">{message}</div>;
};
});
test('renders parent component with mocked child', () => {
render(<ParentComponent />);
const mockedChild = screen.getByTestId('mock-child');
expect(mockedChild).toBeInTheDocument();
});Mocking Named Exports
If your component uses named exports, the mock structure changes
slightly because jest.mock() must return an object
containing the named component.
// ChildComponent.js
export function NamedChild({ message }) {
return <div>Real Named Child: {message}</div>;
}Mock the named export by returning an object where the key matches the exported component name:
import { render, screen } from '@testing-library/react';
import ParentComponent from './ParentComponent';
// Mock the named export
jest.mock('./ChildComponent', () => ({
NamedChild: ({ message }) => <div data-testid="mock-named-child">{message}</div>
}));
test('renders parent with mocked named child', () => {
render(<ParentComponent />);
const mockedChild = screen.getByTestId('mock-named-child');
expect(mockedChild).toBeInTheDocument();
});Mocking to Inspect Passed Props
Sometimes you need to verify that the parent component passes the
correct props to the child component. You can achieve this by assigning
a Jest mock function (jest.fn()) to the mocked
component.
import { render } from '@testing-library/react';
import ParentComponent from './ParentComponent';
import ChildComponent from './ChildComponent';
// Create a mock function to capture props
const mockChildRender = jest.fn();
jest.mock('./ChildComponent', () => {
return function MockChild(props) {
mockChildRender(props);
return <div data-testid="mock-child" />;
};
});
test('passes correct props to child component', () => {
render(<ParentComponent customProp="test-value" />);
// Verify the props passed to the child component
expect(mockChildRender).toHaveBeenCalledWith(
expect.objectContaining({
customProp: 'test-value'
})
);
});