1--- 2title: Testing 3description: Learn how to create integration tests for your app when using Expo Router. 4--- 5 6import { APIBox } from '~/components/plugins/APIBox'; 7 8Expo 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`](https://callstack.github.io/react-native-testing-library/) and allows you to quickly create in-memory Expo Router apps that are pre-configured for testing. 9 10## Configuration 11 12Before you proceed, ensure you've set up `jest-expo` according to the [Unit Testing](/develop/unit-testing/) and [`@testing-library/react-native`](https://callstack.github.io/react-native-testing-library/docs/getting-started). 13 14## `renderRouter` 15 16`renderRouter` extends the functionality of [`render`](https://callstack.github.io/react-native-testing-library/docs/api#render) to simplify testing with Expo Router. It returns the same query object as [`render`](https://callstack.github.io/react-native-testing-library/docs/api#render), and is compatible with [`screen`](https://callstack.github.io/react-native-testing-library/docs/api#screen), allowing you to use the standard [query API](https://callstack.github.io/react-native-testing-library/docs/api-queries) to locate components. 17 18`renderRouter` accepts the same [options](https://callstack.github.io/react-native-testing-library/docs/api#render-options) as `render` and introduces an additional option `initialRoute`, which sets an initial route for simulating deep-linking. 19 20<APIBox header="Inline file system"> 21 22`renderRouter(mock: Record<string, ReactComponent>, options: RenderOptions)` 23 24`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.** 25 26```tsx app.test.tsx 27import { renderRouter, screen } from 'expo-router/testing-library'; 28 29it('my-test', async () => { 30 const MockComponent = jest.fn(() => <View />); 31 32 renderRouter( 33 { 34 index: MockComponent, 35 'folder/a': MockComponent, 36 '(group)/b': MockComponent, 37 }, 38 { 39 initialRoute: '/folder/a', 40 } 41 ); 42 43 expect(screen).toHavePathname('/folder/a'); 44}); 45``` 46 47</APIBox> 48 49<APIBox header="Path to fixture"> 50 51`renderRouter(fixturePath: string, options: RenderOptions)` 52 53`renderRouter` can accept a directory path to mock an existing fixture. Ensure that the provided path is relative to the current test file. 54 55```tsx app.test.js 56it('my-test', async () => { 57 const MockComponent = jest.fn(() => <View />); 58 renderRouter('./my-test-fixture'); 59}); 60``` 61 62</APIBox> 63 64<APIBox header="Path to the fixture with overrides"> 65 66`renderRouter({ appDir: string, overrides: Record<string, ReactComponent>}, options: RenderOptions)` 67 68For 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 folder. 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. 69 70```tsx app.test.js 71it('my-test', async () => { 72 const MockAuthLayout = jest.fn(() => <View />); 73 renderRouter({ 74 appDir: './my-test-fixture', 75 overrides: { 76 'folder/(auth)/_layout': MockAuthLayout, 77 }, 78 }); 79}); 80``` 81 82</APIBox> 83 84## Jest matchers 85 86The following matches have been added to `expect` and can be used to asset values on `screen`. 87 88<APIBox header="toHavePathname()"> 89 90Assert the current pathname against a given string. The matcher uses the value of the [`usePathname`](/router/reference/hooks/#usepathname) hook on the current `screen`. 91 92```tsx app.test.ts 93expect(screen).toHavePathname('/my-router'); 94``` 95 96</APIBox> 97<APIBox header="toHaveSegments()"> 98 99Assert the current segments against an array of strings. The matcher uses the value of the [`useSegments`](/router/reference/hooks/#usesegments) hook on the current `screen`. 100 101```tsx app.test.ts 102expect(screen).toHaveSegments(['[id]']); 103``` 104 105</APIBox> 106<APIBox header="useLocalSearchParams"> 107 108Assert the current local search parameters against an object. The matcher uses the value of the [`useLocalSearchParams`](/router/reference/hooks/#uselocalsearchparams) hook on the current `screen`. 109 110```tsx app.test.ts 111expect(screen).useLocalSearchParams({ first: 'abc' }); 112``` 113 114</APIBox> 115<APIBox header="useGlobalSearchParams"> 116 117Assert the current screen's pathname that matches a value. Compares using the value of [`useGlobalSearchParams`](/router/reference/hooks/#useglobalsearchparams) hook. 118 119Assert the current global search parameters against an object. The matcher uses the value of the [`useGlobalSearchParams`](/router/reference/hooks/#useglobalsearchparams) hook on the current `screen`. 120 121```tsx app.test.ts 122expect(screen).useGlobalSearchParams({ first: 'abc' }); 123``` 124 125</APIBox> 126