# Testing Material-UI Components with createRenderer: Best Practices and Implementation Guide

> Learn best practices for testing Material-UI components with createRenderer. Effortlessly configure theme, cache, and portal for reliable unit and integration tests.

- Repository: [MUI/material-ui](https://github.com/mui/material-ui)
- Tags: testing
- Published: 2026-02-26

---

**Use `createRenderer` from `@mui/material/test-utils` to automatically configure the theme, Emotion cache, and portal containers required for reliable unit and integration tests of Material-UI components.**

Testing Material-UI components with `createRenderer` eliminates the repetitive boilerplate of manually wrapping components with `ThemeProvider` and `CacheProvider` in every test file. This utility, maintained in the `mui/material-ui` repository, extends React Testing Library to provide automatic styling engine configuration, theme injection, and portal container management.

## What is createRenderer and Why Use It

`createRenderer` is a test utility that returns a `render` function mirroring the React Testing Library API while injecting Material-UI-specific context. According to the source code in [`packages/mui-material/src/test-utils/createRenderer.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/createRenderer.tsx), it automatically wraps your component with a `ThemeProvider` (defaulting to `createTheme()`) and a `CacheProvider` containing a fresh Emotion cache per test.

This architecture prevents style leakage between tests and ensures components relying on global CSS resets behave identically in test and browser environments. The utility also handles portal containers automatically, eliminating manual DOM manipulation for components like `Modal` or `Popover`.

## Core Architecture and Key Features

### Automatic Theme and Cache Isolation

The renderer configures a dedicated `CacheProvider` using a fresh Emotion cache for every test invocation. As implemented in [`packages/mui-material/src/test-utils/createRenderer.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/createRenderer.tsx), this isolation prevents class name collisions and style pollution across test cases. The default theme is generated via `createTheme()` from [`packages/mui-material/src/styles/createTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/styles/createTheme.ts), though you can override this with custom theme objects.

### Portal Container Management

Material-UI components that render via React portals—such as `Modal`, `Menu`, and `Popover`—require a stable DOM attachment point. The utility automatically appends a `<div id="mui-test-root">` to `document.body` before each test, as defined in the portal container logic within [`packages/mui-material/src/test-utils/createRenderer.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/createRenderer.tsx). This ensures predictable portal rendering without manual DOM setup.

### Automatic Cleanup

After each test, `createRenderer` registers React Testing Library's `cleanup` function and clears the Emotion cache. The cleanup logic in [`packages/mui-material/src/test-utils/cleanup.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/cleanup.ts) ensures that styles, portal containers, and rendered components are removed, providing a pristine environment for subsequent tests.

### Extensibility for Integration Testing

Advanced users can pass a custom `theme` object or a `wrapper` option to add additional context providers such as Redux or React Router. The options parameter in [`packages/mui-material/src/test-utils/createRenderer.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/createRenderer.tsx) accepts these configurations while maintaining the automatic MUI-specific setup.

## Practical Implementation Examples

### Testing Basic Components

For standard components like `Button`, the renderer handles theme injection automatically. Import `createRenderer` from `@mui/material/test-utils` and destructure the `render` method to test user interactions.

```tsx
import * as React from 'react';
import Button from '@mui/material/Button';
import { createRenderer } from '@mui/material/test-utils';
import { screen, fireEvent } from '@testing-library/react';

const { render } = createRenderer();

test('Button calls onClick when clicked', () => {
  const handleClick = jest.fn();

  render(<Button onClick={handleClick}>Click me</Button>);

  fireEvent.click(screen.getByRole('button', { name: /click me/i }));
  expect(handleClick).toHaveBeenCalledTimes(1);
});

```

### Testing Portal-Based Components

Components like `Modal` automatically attach to the `#mui-test-root` container created by `createRenderer`. You can query portal content using standard RTL selectors without manual DOM manipulation.

```tsx
import * as React from 'react';
import Modal from '@mui/material/Modal';
import { createRenderer } from '@mui/material/test-utils';
import { screen, fireEvent } from '@testing-library/react';

const { render } = createRenderer();

test('Modal opens and closes', () => {
  const [open, setOpen] = React.useState(true);
  
  render(
    <Modal open={open} onClose={() => setOpen(false)}>
      <div data-testid="modal-content">Hello</div>
    </Modal>
  );

  expect(screen.getByTestId('modal-content')).toBeInTheDocument();

  fireEvent.keyDown(document, { key: 'Escape' });
});

```

### Overriding the Default Theme

Pass a custom `theme` option to `createRenderer` to test components with specific theme configurations, such as custom typography or palette settings.

```tsx
import * as React from 'react';
import { createRenderer } from '@mui/material/test-utils';
import { createTheme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import { screen } from '@testing-library/react';

const customTheme = createTheme({ 
  typography: { 
    h1: { fontSize: '3rem' } 
  } 
});

const { render } = createRenderer({ theme: customTheme });

test('Typography uses custom theme values', () => {
  render(
    <Typography variant="h1" data-testid="title">
      Title
    </Typography>
  );

  expect(screen.getByTestId('title')).toHaveStyle('font-size: 3rem');
});

```

### Integrating Additional Providers

Use the `wrapper` option to add custom context providers such as Redux or React Router while maintaining MUI's automatic theme and cache configuration.

```tsx
import * as React from 'react';
import { createRenderer } from '@mui/material/test-utils';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import Counter from '../Counter';

const mockStore = configureStore([]);
const store = mockStore({ count: 5 });

const { render } = createRenderer({
  wrapper: ({ children }) => <Provider store={store}>{children}</Provider>,
});

test('Counter displays value from Redux store', () => {
  render(<Counter />);
  expect(screen.getByText(/5/)).toBeInTheDocument();
});

```

## Key Source Files in the Material-UI Repository

Understanding the implementation details in the `mui/material-ui` repository helps you extend or debug the testing utility.

| File | Purpose | Link |
|------|---------|------|
| [`packages/mui-material/src/test-utils/createRenderer.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/createRenderer.tsx) | Core utility that builds the RTL `render` function with MUI‑specific wrappers (theme, cache, portal container). | [view source](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/test-utils/createRenderer.tsx) |
| [`packages/mui-material/src/test-utils/themeProvider.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/themeProvider.tsx) | Helper that supplies the default `ThemeProvider` and optional `CssBaseline`. | [view source](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/test-utils/themeProvider.tsx) |
| [`packages/mui-material/src/styles/createTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/styles/createTheme.ts) | Function to generate MUI themes; frequently imported in tests to customise styling. | [view source](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/styles/createTheme.ts) |
| [`packages/mui-material/src/styles/cache.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/styles/cache.ts) | Defines the Emotion cache creation used by `createRenderer`. | [view source](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/styles/cache.ts) |
| [`packages/mui-material/src/test-utils/cleanup.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/cleanup.ts) | Registers RTL’s `cleanup` and clears the Emotion cache after each test. | [view source](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/test-utils/cleanup.ts) |

## Summary

- **Use `createRenderer`** from `@mui/material/test-utils` to eliminate manual `ThemeProvider` and `CacheProvider` boilerplate in every test file.
- **Automatic isolation** via fresh Emotion caches and dedicated portal containers (`#mui-test-root`) prevents style leakage and DOM pollution between tests.
- **Extensible architecture** supports custom themes via the `theme` option and additional context providers (Redux, Router) via the `wrapper` option.
- **Automatic cleanup** removes rendered components, portal containers, and cached styles after each test, ensuring a pristine environment.

## Frequently Asked Questions

### What is the difference between createRenderer and React Testing Library's render?

`createRenderer` wraps React Testing Library's `render` function with Material-UI-specific providers. While RTL's native `render` requires manual setup of `ThemeProvider` and `CacheProvider`, `createRenderer` automatically injects these wrappers along with a fresh Emotion cache and portal container, ensuring consistent styling and DOM isolation for MUI components.

### How do I test components that use React portals with createRenderer?

You do not need manual DOM setup. `createRenderer` automatically creates a `<div id="mui-test-root">` container and attaches it to `document.body` before each test, as implemented in [`packages/mui-material/src/test-utils/createRenderer.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/createRenderer.tsx). Portal-based components like `Modal` and `Popover` automatically render into this container, which is cleaned up after each test.

### Can I use createRenderer with Redux or React Router?

Yes. Pass a custom `wrapper` option to `createRenderer` to inject additional context providers. The utility composes your custom wrapper with its internal `ThemeProvider` and `CacheProvider`, allowing you to test integrated components while maintaining automatic MUI configuration.

### Where is the cleanup logic handled in createRenderer?

The cleanup logic is implemented in [`packages/mui-material/src/test-utils/cleanup.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/test-utils/cleanup.ts) and automatically registered by `createRenderer`. After each test, it invokes React Testing Library's `cleanup` function and clears the Emotion cache, ensuring that styles, portal containers, and rendered components do not leak between tests.