📄 expo/router/reference/testing

File: testing.md | Updated: 11/15/2025

Source: https://docs.expo.dev/router/reference/testing

Hide navigation

Search

Ctrl K

Home Guides EAS Reference Learn

Archive Expo Snack Discord and Forums Newsletter

Testing configuration for Expo Router

Edit page

Copy page

Learn how to create integration tests for your app when using Expo Router.

Edit page

Copy page


Expo Router relies on your file system, which can present challenges when setting up mocks for integration tests. Expo Router's submodule, expo-router/testing-library, is a set of testing utilities built on top of the popular @testing-library/react-native and allows you to quickly create in-memory Expo Router apps that are pre-configured for testing.

Configuration


Before you proceed, ensure you have set up jest-expo according to the Unit testing with Jest and @testing-library/react-native in your project.

Note: When using Expo Router, do not put your test files inside the app directory. All files inside your app directory must be either routes or layout files. Instead, use the __tests__ directory or a separate directory. This approach is explained in Unit testing with Jest .

renderRouter


renderRouter extends the functionality of render to simplify testing with Expo Router. It returns the same query object as render , and is compatible with screen , allowing you to use the standard query API to locate components.

renderRouter accepts the same options as render and introduces an additional option initialUrl, which sets an initial route for simulating deep-linking.

Inline file system

renderRouter(mock: Record<string, ReactComponent>, options: RenderOptions)

renderRouter can provide inline-mocking of a file system by passing an object to this function as the first parameter. The keys of the object are the mock filesystem paths. Do not use leading relative (./) or absolute (/) notation when defining these paths and exclude file extension.

app.test.tsx

Copy

import { renderRouter, screen } from 'expo-router/testing-library'; it('my-test', async () => { const MockComponent = jest.fn(() => <View />); renderRouter( { index: MockComponent, 'directory/a': MockComponent, '(group)/b': MockComponent, }, { initialUrl: '/directory/a', } ); expect(screen).toHavePathname('/directory/a'); });

Show More

Inline file system with `null` components

renderRouter(mock: string[], options: RenderOptions)

Providing an array of strings to renderRouter will create an inline mock filesystem with null components ({ default: () => null }). This is useful for testing scenarios where you do not need to test the output of a route.

app.test.tsx

Copy

import { renderRouter, screen } from 'expo-router/testing-library'; it('my-test', async () => { renderRouter(['index', 'directory/a', '(group)/b'], { initialUrl: '/directory/a', }); expect(screen).toHavePathname('/directory/a'); });

Path to fixture

renderRouter(fixturePath: string, options: RenderOptions)

renderRouter can accept a directory path to mock an existing fixture. Ensure that the provided path is relative to the current test file.

app.test.js

Copy

it('my-test', async () => { const MockComponent = jest.fn(() => <View />); renderRouter('./my-test-fixture'); });

Path to the fixture with overrides

renderRouter({ appDir: string, overrides: Record<string, ReactComponent>}, options: RenderOptions)

For more intricate testing scenarios, renderRouter can leverage both directory path and inline-mocking methods simultaneously. The appDir parameter takes a string representing a pathname to a directory. The overrides parameter is an inline mock that can be used to override specific paths within the appDir. This combination allows for fine-tuned control over the mock environment.

app.test.js

Copy

it('my-test', async () => { const MockAuthLayout = jest.fn(() => <View />); renderRouter({ appDir: './my-test-fixture', overrides: { 'directory/(auth)/_layout': MockAuthLayout, }, }); });

Jest matchers


The following matches have been added to expect and can be used to assert values on screen.

toHavePathname()

Assert the current pathname against a given string. The matcher uses the value of the usePathname hook on the current screen.

app.test.ts

Copy

expect(screen).toHavePathname('/my-router');

toHavePathnameWithParams()

Assert the current pathname, including URL parameters, against a given string. This is useful to assert the appearance of URL in a web browser.

app.test.ts

Copy

expect(screen).toHavePathnameWithParams('/my-router?hello=world');

toHaveSegments()

Assert the current segments against an array of strings. The matcher uses the value of the useSegments hook on the current screen.

app.test.ts

Copy

expect(screen).toHaveSegments(['[id]']);

useLocalSearchParams()

Assert the current local URL parameters against an object. The matcher uses the value of the useLocalSearchParams hook on the current screen.

app.test.ts

Copy

expect(screen).useLocalSearchParams({ first: 'abc' });

useGlobalSearchParams()

Assert the current screen's pathname that matches a value. Compares using the value of useGlobalSearchParams hook.

Assert the current global URL parameters against an object. The matcher uses the value of the useGlobalSearchParams hook on the current screen.

app.test.ts

Copy

expect(screen).useGlobalSearchParams({ first: 'abc' });

toHaveRouterState()

An advanced matcher that asserts the current router state against an object.

app.test.ts

Copy

expect(screen).toHaveRouterState({ routes: [{ name: 'index', path: '/' }], });