@@ -302,6 +302,136 @@ test('pushes settings screen twice', () => {
302302</TabItem >
303303</Tabs >
304304
305+ For writing tests that include times functions we will have to use [ Fake Timers] ( https://jestjs.io/docs/timer-mocks ) . They will replace times function implementation to use time from the fake clock.
306+
307+ Let's add another button, which uses ` setTimeout ` , to the previously defined ` Profile ` screen:
308+
309+ <Tabs groupId =" example " queryString =" example " >
310+ <TabItem value =" static " label =" Static " default >
311+
312+ ``` js
313+ const ProfileScreen = () => {
314+ const navigation = useNavigation ();
315+ return (
316+ < View>
317+ < Text > Profile Screen< / Text >
318+ < Button
319+ onPress= {() => navigation .navigate (' Settings' )}
320+ title= " Navigate to Settings"
321+ / >
322+ < Button
323+ onPress= {() => navigation .push (' Settings' )}
324+ title= " Push Settings"
325+ / >
326+ {/* Added button */ }
327+ < Button
328+ onPress= {() => setTimeout (() => navigation .navigate (' Settings' ), 10000 )}
329+ title= " Navigate to Settings with 10000 ms delay"
330+ / >
331+ < / View>
332+ );
333+ };
334+ ```
335+
336+ </TabItem >
337+ <TabItem value =" dynamic " label =" Dynamic " >
338+
339+ ``` js
340+ const ProfileScreen = ({ navigation }) => {
341+ return (
342+ < View>
343+ < Text > Profile Screen< / Text >
344+ < Button
345+ onPress= {() => navigation .navigate (' Settings' )}
346+ title= " Navigate to Settings"
347+ / >
348+ < Button
349+ onPress= {() => navigation .push (' Settings' )}
350+ title= " Push Settings"
351+ / >
352+ {/* Added button */ }
353+ < Button
354+ onPress= {() => setTimeout (() => navigation .navigate (' Settings' ), 10000 )}
355+ title= " Navigate to Settings with 10000 ms delay"
356+ / >
357+ < / View>
358+ );
359+ };
360+ ```
361+
362+ </TabItem >
363+ </Tabs >
364+
365+ Fake timers test example:
366+
367+ <Tabs groupId =" example " queryString =" example " >
368+ <TabItem value =" static " label =" Static " default >
369+
370+ ``` js
371+ import { expect , jest , test } from ' @jest/globals' ;
372+ import { act , fireEvent , render , screen } from ' @testing-library/react-native' ;
373+ import { createStaticNavigation } from ' @react-navigation/native' ;
374+ import { RootNavigator } from ' ./RootNavigator' ;
375+
376+ test (' navigates to settings screen after 10000 ms delay' , () => {
377+ // Enable fake timers
378+ jest .useFakeTimers ();
379+
380+ const RootNavigation = createStaticNavigation (RootNavigator);
381+ render (< RootNavigation / > );
382+
383+ fireEvent .press (screen .getByText (' Navigate to Settings with 10000 ms delay' ));
384+
385+ act (() => jest .advanceTimersByTime (5000 ));
386+
387+ expect (screen .queryByText (' Profile Screen' )).toBeOnTheScreen ();
388+ expect (screen .queryByText (' Settings Screen' )).not .toBeOnTheScreen ();
389+
390+ act (() => jest .advanceTimersByTime (5000 ));
391+
392+ expect (screen .queryByText (' Profile Screen' )).not .toBeOnTheScreen ();
393+ expect (screen .queryByText (' Settings Screen' )).toBeOnTheScreen ();
394+ });
395+ ```
396+
397+ </TabItem >
398+ <TabItem value =" dynamic " label =" Dynamic " >
399+
400+ ``` js
401+ import { expect , jest , test } from ' @jest/globals' ;
402+ import { act , fireEvent , render , screen } from ' @testing-library/react-native' ;
403+ import { NavigationContainer } from ' @react-navigation/native' ;
404+ import { RootNavigator } from ' ./RootNavigator' ;
405+
406+ test (' navigates to settings screen after 10000 ms delay' , () => {
407+ // Enable fake timers
408+ jest .useFakeTimers ();
409+
410+ render (
411+ < NavigationContainer>
412+ < RootNavigator / >
413+ < / NavigationContainer>
414+ );
415+
416+ fireEvent .press (screen .getByText (' Navigate to Settings with 10000 ms delay' ));
417+
418+ // jest.advanceTimersByTime causes React state updates
419+ // So it should be wrapped into act
420+ act (() => jest .advanceTimersByTime (5000 ));
421+
422+ expect (screen .queryByText (' Profile Screen' )).toBeOnTheScreen ();
423+ expect (screen .queryByText (' Settings Screen' )).not .toBeOnTheScreen ();
424+
425+ act (() => jest .advanceTimersByTime (5000 ));
426+
427+ expect (screen .queryByText (' Profile Screen' )).not .toBeOnTheScreen ();
428+ expect (screen .queryByText (' Settings Screen' )).toBeOnTheScreen ();
429+ });
430+ ```
431+
432+ </TabItem >
433+ </Tabs >
434+
305435To show how drawer's screens ` preload ` works, we will compare two tests - with and without preloading.
306436
307437Without preloading test example:
@@ -580,138 +710,6 @@ test('navigates to settings with previous preload', () => {
580710</TabItem >
581711</Tabs >
582712
583- For writing tests that include times functions we will have to use [ Fake Timers] ( https://jestjs.io/docs/timer-mocks ) . They will replace times function implementation to use time from the fake clock.
584-
585- Let's add another button to the Profile screen, which uses ` setTimeout ` :
586-
587- <Tabs groupId =" example " queryString =" example " >
588- <TabItem value =" static " label =" Static " default >
589-
590- ``` js
591- const ProfileScreen = () => {
592- const navigation = useNavigation ();
593- return (
594- < View>
595- < Text > Profile Screen< / Text >
596- < Button
597- onPress= {() => navigation .navigate (' Settings' )}
598- title= " Navigate to Settings"
599- / >
600- < Button
601- onPress= {() => navigation .push (' Settings' )}
602- title= " Push Settings"
603- / >
604- {/* Added button */ }
605- < Button
606- onPress= {() => setTimeout (() => navigation .navigate (' Settings' ), 10000 )}
607- title= " Navigate to Settings with 10000 ms delay"
608- / >
609- < / View>
610- );
611- };
612- ```
613-
614- </TabItem >
615- <TabItem value =" dynamic " label =" Dynamic " >
616-
617- ``` js
618- const ProfileScreen = ({ navigation }) => {
619- return (
620- < View>
621- < Text > Profile Screen< / Text >
622- < Button
623- onPress= {() => navigation .navigate (' Settings' )}
624- title= " Navigate to Settings"
625- / >
626- < Button
627- onPress= {() => navigation .push (' Settings' )}
628- title= " Push Settings"
629- / >
630- {/* Added button */ }
631- < Button
632- onPress= {() => setTimeout (() => navigation .navigate (' Settings' ), 10000 )}
633- title= " Navigate to Settings with 10000 ms delay"
634- / >
635- < / View>
636- );
637- };
638- ```
639-
640- </TabItem >
641- </Tabs >
642-
643- Fake timers test example:
644-
645- <Tabs groupId =" example " queryString =" example " >
646- <TabItem value =" static " label =" Static " default >
647-
648- ``` js
649- import { expect , jest , test } from ' @jest/globals' ;
650- import { act , fireEvent , render , screen } from ' @testing-library/react-native' ;
651- import { createStaticNavigation } from ' @react-navigation/native' ;
652- import { RootNavigator } from ' ./RootNavigator' ;
653-
654- test (' navigates to settings screen after 10000 ms delay' , () => {
655- // Enable fake timers
656- jest .useFakeTimers ();
657-
658- const RootNavigation = createStaticNavigation (RootNavigator);
659- render (< RootNavigation / > );
660-
661- fireEvent .press (screen .getByText (' Navigate to Settings with 10000 ms delay' ));
662-
663- // jest.advanceTimersByTime causes React state updates
664- // So it should be wrapped into act
665- act (() => jest .advanceTimersByTime (5000 ));
666-
667- expect (screen .queryByText (' Profile Screen' )).toBeOnTheScreen ();
668- expect (screen .queryByText (' Settings Screen' )).not .toBeOnTheScreen ();
669-
670- act (() => jest .advanceTimersByTime (5000 ));
671-
672- expect (screen .queryByText (' Profile Screen' )).not .toBeOnTheScreen ();
673- expect (screen .queryByText (' Settings Screen' )).toBeOnTheScreen ();
674- });
675- ```
676-
677- </TabItem >
678- <TabItem value =" dynamic " label =" Dynamic " >
679-
680- ``` js
681- import { expect , jest , test } from ' @jest/globals' ;
682- import { act , fireEvent , render , screen } from ' @testing-library/react-native' ;
683- import { NavigationContainer } from ' @react-navigation/native' ;
684- import { RootNavigator } from ' ./RootNavigator' ;
685-
686- test (' navigates to settings screen after 10000 ms delay' , () => {
687- // Enable fake timers
688- jest .useFakeTimers ();
689-
690- render (
691- < NavigationContainer>
692- < RootNavigator / >
693- < / NavigationContainer>
694- );
695-
696- fireEvent .press (screen .getByText (' Navigate to Settings with 10000 ms delay' ));
697-
698- // jest.advanceTimersByTime causes React state updates
699- // So it should be wrapped into act
700- act (() => jest .advanceTimersByTime (5000 ));
701-
702- expect (screen .queryByText (' Profile Screen' )).toBeOnTheScreen ();
703- expect (screen .queryByText (' Settings Screen' )).not .toBeOnTheScreen ();
704-
705- act (() => jest .advanceTimersByTime (5000 ));
706-
707- expect (screen .queryByText (' Profile Screen' )).not .toBeOnTheScreen ();
708- expect (screen .queryByText (' Settings Screen' )).toBeOnTheScreen ();
709- });
710- ```
711-
712- </TabItem >
713- </Tabs >
714-
715713## Best practices
716714
717715There are a couple of things to keep in mind when writing tests for components using React Navigation:
0 commit comments