# Context, Providers and Routing — Jest, Vitest & Testing Library

Source: https://www.skillbyai.com/en/javascript-testing/x-providers

> A custom render wrapper.

## Render with the same providers as the app

Real components depend on **context**: a theme, an auth session, a data-fetching client such as TanStack Query, i18n and a **router**. Rendering them bare throws or behaves unrealistically. Write a **custom render** that wraps the UI in the app's providers via the `wrapper` option, accepts options such as an initial route or user, and re-exports everything from Testing Library, so tests import `render` from your test utils. Create a **fresh** store or query client per test to keep isolation (and turn off retries in tests so error states appear quickly). For routing, use an in-memory router such as React Router's `MemoryRouter` with `initialEntries`; package names differ between React Router versions, so check the docs for yours.

## test-utils.tsx with a wrapper

Assumes React Router and TanStack Query; adapt to your stack.

```tsx
// src/test/test-utils.tsx
import type { ReactElement, ReactNode } from 'react';
import { render, type RenderOptions } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { MemoryRouter } from 'react-router-dom';
import { AuthProvider, type User } from '../auth';

type Options = Omit<RenderOptions, 'wrapper'> & { route?: string; user?: User | null };

export function renderWithProviders(ui: ReactElement, { route = '/', user = null, ...options }: Options = {}) {
  const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });

  function Wrapper({ children }: { children: ReactNode }) {
    return (
      <QueryClientProvider client={queryClient}>
        <AuthProvider initialUser={user}>
          <MemoryRouter initialEntries={[route]}>{children}</MemoryRouter>
        </AuthProvider>
      </QueryClientProvider>
    );
  }
  return render(ui, { wrapper: Wrapper, ...options });
}

export * from '@testing-library/react';

// in a test
// renderWithProviders(<AccountPage />, { route: '/account', user: buildUser({ name: 'Asha' }) });
```

## A stage with the lights on

Rendering a component without its providers is like rehearsing a play in an empty warehouse with no lights or props. The custom render builds the real stage once, so every rehearsal looks like opening night.

**Quiz:** Why create a new QueryClient (or store) inside the custom render?

- [ ] Because providers cannot be reused in production
- [x] So cached data and state do not leak from one test into another
- [ ] To make tests run in a real browser
- [ ] To increase coverage numbers

*Answer:* So cached data and state do not leak from one test into another. Fresh state per test keeps tests isolated.
