How to Mock React Server Components
Mocking React Server Components (RSCs) is a crucial skill for testing modern Next.js and React applications. Because Server Components run exclusively on the server and often fetch data directly using async/await, traditional client-side testing strategies do not always apply. This article provides a straightforward guide on how to mock Server Components using Jest or Vitest, as well as how to mock their underlying data-fetching layers for more reliable integration tests.
Why Mock Server Components?
React Server Components often execute server-only code, such as direct database queries, secure API calls using private environment variables, or filesystem operations. If you attempt to render these components in a standard test environment (like JSDOM), the tests will fail due to missing server APIs or network access. Mocking allows you to isolate your client components or parent components without executing the complex server-side logic of their children.
Method 1: Mocking the Component Module
The simplest way to mock a Server Component is to replace the module import with a dummy client component during your unit tests. This is highly effective when you are testing a parent Client Component and want to ignore the rendering behavior of a child Server Component.
If you are using Jest or Vitest, you can use module mocking:
import { render, screen } from '@testing-library/react';
import ParentComponent from './ParentComponent';
import { vi, describe, it, expect } from 'vitest';
// Mock the Server Component child
vi.mock('./MyServerComponent', () => {
return {
default: () => <div data-testid="mock-server-component">Mocked Server Content</div>
};
});
describe('ParentComponent', () => {
it('renders the mocked server component inside parent', () => {
render(<ParentComponent />);
expect(screen.getByTestId('mock-server-component')).toBeInTheDocument();
});
});Method 2: Mocking the Data Fetching Layer
Often, you do not want to mock the entire Server Component itself because you want to verify that it renders the correct UI based on server data. Instead, you should mock the data fetch call or the SDK that the Server Component relies on.
Mocking Global Fetch
If your Server Component fetches data using the global
fetch API:
// MyServerComponent.jsx
export default async function MyServerComponent() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return <div>Data: {data.message}</div>;
}You can mock the global fetch in your test file:
import { render, screen } from '@testing-library/react';
import MyServerComponent from './MyServerComponent';
import { vi, it, expect } from 'vitest';
it('renders fetched server data', async () => {
// Mock the global fetch
global.fetch = vi.fn().mockResolvedValue({
json: vi.fn().mockResolvedValue({ message: 'Hello from the Server!' }),
});
// Since it is an async server component, resolve it before rendering
const ResolvedComponent = await MyServerComponent();
render(ResolvedComponent);
expect(screen.getByText('Data: Hello from the Server!')).toBeInTheDocument();
});Method 3: Rendering Async Server Components in Tests
React Server Components are asynchronous functions. To test them
directly without mocking, you must resolve the component promise before
passing it to your React Testing Library render
function.
Here is how you can render and test an actual async Server Component:
import { render, screen } from '@testing-library/react';
import MyServerComponent from './MyServerComponent';
it('renders async server component successfully', async () => {
// Await the component function to resolve its JSX output
const ComponentJSX = await MyServerComponent({});
render(ComponentJSX);
expect(screen.getByText(/Data:/i)).toBeInTheDocument();
});Using these three strategies—module mocking, data-layer mocking, and async resolution—you can easily test any component hierarchy that relies on React Server Components.