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.