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 />);
// ...
});