Skip to content

Commit 8f4fd6f

Browse files
committed
add preload test
1 parent c8e9a0c commit 8f4fd6f

File tree

1 file changed

+282
-1
lines changed

1 file changed

+282
-1
lines changed

versioned_docs/version-7.x/testing.md

Lines changed: 282 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ If you're not using Jest, then you'll need to mock these modules according to th
7979

8080
We recommend using [React Native Testing Library](https://callstack.github.io/react-native-testing-library/) along with [`jest-native`](https://github.com/testing-library/jest-native) to write your tests.
8181

82-
We are going to write example tests illustrating the difference between `navigate` and `push` functions using `RootNavigator` defined below:
82+
We are going to write example tests illustrating the difference between `navigate` and `push` functions, drawer's screens `preload` and times functions in tests.
83+
84+
To show the difference between `navigate` and `push` functions, we will use `RootNavigator` defined below:
8385

8486
<Tabs groupId="example" queryString="example">
8587
<TabItem value="static" label="Static" default>
@@ -299,6 +301,285 @@ test('pushes settings screen twice', () => {
299301
</TabItem>
300302
</Tabs>
301303

304+
To show how drawer's screens `preload` works, we will compare two tests - with and without preloading.
305+
306+
Without preloading test example:
307+
308+
<Tabs groupId="example" queryString="example">
309+
<TabItem value="static" label="Static" default>
310+
311+
```js
312+
import { expect, test } from '@jest/globals';
313+
import { createDrawerNavigator } from '@react-navigation/drawer';
314+
import {
315+
createNavigationContainerRef,
316+
createStaticNavigation,
317+
useNavigation,
318+
} from '@react-navigation/native';
319+
import { fireEvent, render, screen } from '@testing-library/react-native';
320+
import { Button, Text, View } from 'react-native';
321+
322+
const Profile = () => {
323+
const navigation = useNavigation();
324+
return (
325+
<View>
326+
<Text>Profile Screen</Text>
327+
<Button
328+
onPress={() => navigation.navigate('Settings')}
329+
title="Navigate to Settings"
330+
/>
331+
</View>
332+
);
333+
};
334+
335+
let renderCounter = 0;
336+
337+
const Settings = () => {
338+
renderCounter++;
339+
return (
340+
<View>
341+
<Text>Settings Screen</Text>
342+
</View>
343+
);
344+
};
345+
346+
const Drawer = createDrawerNavigator({
347+
screens: {
348+
Profile,
349+
Settings,
350+
},
351+
});
352+
353+
const DrawerNavigation = createStaticNavigation(Drawer);
354+
355+
test('navigates to settings without previous preload', () => {
356+
const navigation = createNavigationContainerRef();
357+
render(<DrawerNavigation ref={navigation} />);
358+
359+
expect(screen.queryByText('Profile Screen')).toBeOnTheScreen();
360+
expect(screen.queryByText('Settings Screen')).not.toBeOnTheScreen();
361+
expect(renderCounter).toBe(0);
362+
363+
fireEvent.press(screen.queryByText('Navigate to Settings'));
364+
365+
expect(screen.queryByText('Profile Screen')).not.toBeOnTheScreen();
366+
expect(screen.queryByText('Settings Screen')).toBeOnTheScreen();
367+
expect(renderCounter).toBe(1);
368+
});
369+
```
370+
371+
</TabItem>
372+
<TabItem value="dynamic" label="Dynamic">
373+
374+
```js
375+
import { expect, test } from '@jest/globals';
376+
import { createDrawerNavigator } from '@react-navigation/drawer';
377+
import {
378+
createNavigationContainerRef,
379+
NavigationContainer,
380+
} from '@react-navigation/native';
381+
import { fireEvent, render, screen } from '@testing-library/react-native';
382+
import { Button, Text, View } from 'react-native';
383+
384+
const Profile = ({ navigation }) => {
385+
return (
386+
<View>
387+
<Text>Profile Screen</Text>
388+
<Button
389+
onPress={() => navigation.navigate('Settings')}
390+
title="Navigate to Settings"
391+
/>
392+
</View>
393+
);
394+
};
395+
396+
let renderCounter = 0;
397+
398+
const Settings = () => {
399+
renderCounter++;
400+
return (
401+
<View>
402+
<Text>Settings Screen</Text>
403+
</View>
404+
);
405+
};
406+
407+
const Drawer = createDrawerNavigator();
408+
409+
const DrawerNavigation = () => {
410+
return (
411+
<Drawer.Navigator>
412+
<Drawer.Screen name="Profile" component={Profile} />
413+
<Drawer.Screen name="Settings" component={Settings} />
414+
</Drawer.Navigator>
415+
);
416+
};
417+
418+
test('navigates to settings without previous preload', () => {
419+
const navigation = createNavigationContainerRef();
420+
render(
421+
<NavigationContainer ref={navigation}>
422+
<DrawerNavigation />
423+
</NavigationContainer>
424+
);
425+
426+
expect(screen.queryByText('Profile Screen')).toBeOnTheScreen();
427+
expect(screen.queryByText('Settings Screen')).not.toBeOnTheScreen();
428+
expect(renderCounter).toBe(0);
429+
430+
fireEvent.press(screen.queryByText('Navigate to Settings'));
431+
432+
expect(screen.queryByText('Profile Screen')).not.toBeOnTheScreen();
433+
expect(screen.queryByText('Settings Screen')).toBeOnTheScreen();
434+
expect(renderCounter).toBe(1);
435+
});
436+
```
437+
438+
</TabItem>
439+
</Tabs>
440+
441+
With preloading test example:
442+
<Tabs groupId="example" queryString="example">
443+
<TabItem value="static" label="Static" default>
444+
445+
```js
446+
import { expect, test } from '@jest/globals';
447+
import { createDrawerNavigator } from '@react-navigation/drawer';
448+
import {
449+
createNavigationContainerRef,
450+
createStaticNavigation,
451+
useNavigation,
452+
} from '@react-navigation/native';
453+
import { act, fireEvent, render, screen } from '@testing-library/react-native';
454+
import { Button, Text, View } from 'react-native';
455+
456+
const Profile = () => {
457+
const navigation = useNavigation();
458+
return (
459+
<View>
460+
<Text>Profile Screen</Text>
461+
<Button
462+
onPress={() => navigation.navigate('Settings')}
463+
title="Navigate to Settings"
464+
/>
465+
</View>
466+
);
467+
};
468+
469+
let renderCounter = 0;
470+
471+
const Settings = () => {
472+
renderCounter++;
473+
return (
474+
<View>
475+
<Text>Settings Screen</Text>
476+
</View>
477+
);
478+
};
479+
480+
const Drawer = createDrawerNavigator({
481+
screens: {
482+
Profile,
483+
Settings,
484+
},
485+
});
486+
487+
const DrawerNavigation = createStaticNavigation(Drawer);
488+
489+
test('navigates to settings with previous preload', () => {
490+
const navigation = createNavigationContainerRef();
491+
render(<DrawerNavigation ref={navigation} />);
492+
493+
expect(renderCounter).toBe(0);
494+
495+
act(() => navigation.preload('Settings'));
496+
497+
expect(screen.queryByText('Profile Screen')).toBeOnTheScreen();
498+
expect(screen.queryByText('Settings Screen')).not.toBeOnTheScreen();
499+
expect(renderCounter).toBe(1);
500+
501+
fireEvent.press(screen.queryByText('Navigate to Settings'));
502+
503+
expect(screen.queryByText('Profile Screen')).not.toBeOnTheScreen();
504+
expect(screen.queryByText('Settings Screen')).toBeOnTheScreen();
505+
expect(renderCounter).toBe(1);
506+
});
507+
```
508+
509+
</TabItem>
510+
<TabItem value="dynamic" label="Dynamic">
511+
512+
```js
513+
import { expect, test } from '@jest/globals';
514+
import { createDrawerNavigator } from '@react-navigation/drawer';
515+
import {
516+
createNavigationContainerRef,
517+
NavigationContainer,
518+
} from '@react-navigation/native';
519+
import { act, fireEvent, render, screen } from '@testing-library/react-native';
520+
import { Button, Text, View } from 'react-native';
521+
522+
const Profile = ({ navigation }) => {
523+
return (
524+
<View>
525+
<Text>Profile Screen</Text>
526+
<Button
527+
onPress={() => navigation.navigate('Settings')}
528+
title="Navigate to Settings"
529+
/>
530+
</View>
531+
);
532+
};
533+
534+
let renderCounter = 0;
535+
536+
const Settings = () => {
537+
renderCounter++;
538+
return (
539+
<View>
540+
<Text>Settings Screen</Text>
541+
</View>
542+
);
543+
};
544+
545+
const Drawer = createDrawerNavigator();
546+
547+
const DrawerNavigation = () => {
548+
return (
549+
<Drawer.Navigator>
550+
<Drawer.Screen name="Profile" component={Profile} />
551+
<Drawer.Screen name="Settings" component={Settings} />
552+
</Drawer.Navigator>
553+
);
554+
};
555+
556+
test('navigates to settings with previous preload', () => {
557+
const navigation = createNavigationContainerRef();
558+
render(
559+
<NavigationContainer ref={navigation}>
560+
<DrawerNavigation />
561+
</NavigationContainer>
562+
);
563+
564+
expect(renderCounter).toBe(0);
565+
566+
act(() => navigation.preload('Settings'));
567+
568+
expect(screen.queryByText('Profile Screen')).toBeOnTheScreen();
569+
expect(screen.queryByText('Settings Screen')).not.toBeOnTheScreen();
570+
expect(renderCounter).toBe(1);
571+
572+
fireEvent.press(screen.queryByText('Navigate to Settings'));
573+
574+
expect(screen.queryByText('Profile Screen')).not.toBeOnTheScreen();
575+
expect(screen.queryByText('Settings Screen')).toBeOnTheScreen();
576+
expect(renderCounter).toBe(1);
577+
});
578+
```
579+
580+
</TabItem>
581+
</Tabs>
582+
302583
For writing tests that include times functions you will need to use [Fake Timers](https://jestjs.io/docs/timer-mocks). They will replace times function implementation to use time from the fake clock.
303584

304585
Let's add another button to the Profile screen, which uses `setTimeout`:

0 commit comments

Comments
 (0)