Skip to Content
We're improving our docs. Share your experience and help shape what comes next.
DocumentationLedger WalletContributing to Ledger WalletHow-to GuidesHow to Use the Custom Renderer

How to Use the Custom Test Renderer

This guide shows you how to use the custom render utilities provided by Ledger Wallet to test components and hooks with all necessary providers pre-configured.

Always prefer the custom render utilities over raw @testing-library render functions.


How to render a component (Mobile)

Import from @tests/test-renderer:

import { render, screen } from "@tests/test-renderer"; import { State } from "~/reducers/types"; const { user, store } = render(<MyComponent />, { overrideInitialState: (state: State) => ({ ...state, accounts: { ...state.accounts, active: [mockAccount], }, }), }); // Use screen queries expect(screen.getByText("Hello")).toBeTruthy(); // Simulate user interactions await user.press(screen.getByText("Submit"));

How to render a component (Desktop)

Import from tests/testSetup:

import { render, screen } from "tests/testSetup"; const { user, store, i18n } = render(<MyComponent />, { initialState: { accounts: { active: [mockAccount] }, }, initialRoute: "/accounts", // Optional: set initial route }); // Use screen queries expect(screen.getByText("Hello")).toBeInTheDocument(); // Simulate user interactions await user.click(screen.getByRole("button", { name: "Submit" }));

How to render a hook

Mobile

import { renderHook } from "@tests/test-renderer"; const { result, store } = renderHook(() => useMyCustomHook(), { overrideInitialState: (state) => ({ ...state, settings: { ...state.settings, theme: "dark" }, }), }); expect(result.current.value).toBe(expectedValue);

Desktop

import { renderHook } from "tests/testSetup"; const { result, store } = renderHook(() => useMyCustomHook(), { initialState: { settings: { theme: "dark" }, }, }); expect(result.current.value).toBe(expectedValue);

How to customize initial state

Use overrideInitialState (Mobile) or initialState (Desktop) to set up Redux state for your tests:

  • Mobile: Pass a function that receives the full default state and returns the modified state. You must spread the existing state to avoid replacing reducer defaults.
  • Desktop: Pass a partial state object that is merged into the default state.
// Mobile - function-based override render(<MyComponent />, { overrideInitialState: (state: State) => ({ ...state, settings: { ...state.settings, theme: "dark" }, }), }); // Desktop - object-based override render(<MyComponent />, { initialState: { settings: { theme: "dark" }, }, });

Before vs After: why use the custom renderer

Before (manual provider setup)

This approach requires manually wrapping components with many providers:

import { render } from "@testing-library/react-native"; import { Provider } from "react-redux"; import { ThemeProvider } from "styled-components"; import { NavigationContainer } from "@react-navigation/native"; import { FirebaseFeatureFlagsProvider } from "~/components/FirebaseFeatureFlags"; // ... many more imports const mockStore = createMockStore({ accounts: [mockAccount] }); render( <Provider store={mockStore}> <FirebaseFeatureFlagsProvider getFeature={getFeature}> <NavigationContainer> <ThemeProvider theme={theme}> <I18nextProvider i18n={i18n}> <MyComponent /> </I18nextProvider> </ThemeProvider> </NavigationContainer> </FirebaseFeatureFlagsProvider> </Provider> );

After (using custom renderer)

The custom renderer handles all provider setup automatically:

import { render, screen } from "@tests/test-renderer"; const { user, store } = render(<MyComponent />, { overrideInitialState: (state) => ({ ...state, accounts: { ...state.accounts, active: [mockAccount] }, }), });

Mocks you no longer need

When using the custom render utilities, remove these commonly unnecessary mocks:

// ❌ No need to mock react-i18next - I18nextProvider is included jest.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key) => key, }), })); // ❌ No need to mock react-redux - Provider with real store is included jest.mock("react-redux", () => ({ useSelector: jest.fn(), useStore: jest.fn(() => ({})), })); // ❌ No need to mock theme-related hooks jest.mock("~/hooks/useTheme", () => ({ useTheme: () => ({ colors: { /* ... */ } }), }));

See also

Last updated on
Ledger
Copyright © Ledger SAS. All rights reserved. Ledger, Ledger Stax, Ledger Flex, Ledger Nano, Ledger Nano S, Ledger OS, Ledger Wallet, [LEDGER] (logo), [L] (logo) are trademarks owned by Ledger SAS.