Custom render function

Summary

RNTL exposes the render function as the primary entry point for tests. If you make complex, repeating setups for your tests, consider creating a custom render function. The idea is to encapsulate common setup steps and test wiring inside a render function suitable for your tests.

Example

test-utils.ts
// ...

interface RenderWithProvidersProps {
  user?: User | null;
  theme?: Theme;
}

export function renderWithProviders<T>(
  ui: React.ReactElement<T>,
  options?: RenderWithProvidersProps
) {
  return render(
    <UserProvider.Provider value={options?.user ?? null}>
      <ThemeProvider.Provider value={options?.theme ?? 'light'}>{ui}</ThemeProvider.Provider>
    </UserProvider.Provider>
  );
}
custom-render/index.test.tsx
import { screen } from '@testing-library/react-native';
import { renderWithProviders } from '../test-utils';
// ...

test('renders WelcomeScreen with user', () => {
  renderWithProviders(<WelcomeScreen />, { user: { name: 'Jar-Jar' } });
  expect(screen.getByText(/hello Jar-Jar/i)).toBeOnTheScreen();
});

test('renders WelcomeScreen without user', () => {
  renderWithProviders(<WelcomeScreen />, { user: null });
  expect(screen.getByText(/hello stranger/i)).toBeOnTheScreen();
});

Example full source code.

More info

Additional params

A custom render function might accept additional parameters to allow for setting up different start conditions for a test, e.g., the initial state for global state management.

SomeScreen.test.tsx
test('renders SomeScreen for logged in user', () => {
  renderScreen(<SomeScreen />, { state: loggedInState });
  // ...
});

Multiple functions

Depending on the situation, you may declare more than one custom render function. For example, you have one function for testing application flows and a second for testing individual screens.

test-utils.tsx
function renderNavigator(ui, options);
function renderScreen(ui, options);

Async function

Make it async if you want to put some async setup in your custom render function.

SomeScreen.test.tsx
test('renders SomeScreen', async () => {
  await renderWithAsync(<SomeScreen />);
  // ...
});