Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6287

Why is the behavior of `jest.useFakeTimers` different when called inside vs. outside of `beforeEach` in React Native

$
0
0

Overview

I encountered different behaviors of jest.useFakeTimers when it is called inside beforeEach versus called outside.

Reproducible Examples

// Foo.tsximport * as React from 'react';import {View} from 'react-native';const Foo: React.FC = () => {  const [timePassed, setTimePassed] = React.useState<number>(0);  const [flag, setFlag] = React.useState(true);  console.log(`timePassed: ${timePassed}, flag: ${flag}`);  React.useEffect(() => {    if (flag) {      setTimeout(() => {        if (timePassed > 1) {          setFlag(false);        }        setTimePassed(timePassed + 1);      }, 1);    }  }, [flag, timePassed]);  return <View />;};export default Foo;
// foo.outside.test.tsximport * as React from 'react';import {render} from '@testing-library/react-native';import Foo from '../Foo';jest.useFakeTimers();describe('Test Foo', () => {  test('1', () => {    render(<Foo />);    jest.runAllTimers();  });  test('2', () => {    render(<Foo />);    jest.runAllTimers();  });});
// foo.inside.test.tsximport * as React from 'react';import {render} from '@testing-library/react-native';import Foo from '../Foo';describe('Test Foo', () => {  // fake timer usage follows: https://testing-library.com/docs/using-fake-timers/  beforeEach(() => {    jest.useFakeTimers();  });  afterEach(() => {    jest.runOnlyPendingTimers();    jest.useRealTimers();  });  test('1', () => {    render(<Foo />);    jest.runAllTimers();  });  test('2', () => {    render(<Foo />);    jest.runAllTimers();  });});

Test Results

outside

$ npx jest __tests__/foo.outside.test.tsx  console.log    timePassed: 0, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 1, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 2, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 2, flag: false      at log (Foo.tsx:8:11)  console.log    timePassed: 3, flag: false      at log (Foo.tsx:8:11)  console.log    timePassed: 0, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 1, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 2, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 2, flag: false      at log (Foo.tsx:8:11)  console.log    timePassed: 3, flag: false      at log (Foo.tsx:8:11) PASS  __tests__/foo.outside.test.tsx  Test Foo✓ 1 (58 ms)✓ 2 (21 ms)

inside

$ npx jest __tests__/foo.inside.test.tsx                      1 ↵  console.log    timePassed: 0, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 1, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 2, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 2, flag: false      at log (Foo.tsx:8:11)  console.log    timePassed: 3, flag: false      at log (Foo.tsx:8:11)  console.log    timePassed: 0, flag: true      at log (Foo.tsx:8:11)  console.log    timePassed: 1, flag: true      at log (Foo.tsx:8:11) PASS  __tests__/foo.inside.test.tsx  Test Foo✓ 1 (62 ms)✓ 2 (14 ms)

Observations

It seems that in the outside setup, jest.runAllTimers runs the timer to the end in both test cases. However, in the inside setup, only the timer in the first test case runs to the end; the timer in the second test case exists prematurely.

Question

Why is the behavior of the fake timer different when jest.useFakeTimers is called inside versus outside beforeEach? I expect both setup to run the timer to the end. Thus, the current behavior of the inside setup is a negative surprise.

Machine and Software Info

  • macOS Big Sur v11.6.5
  • react: 17.0.2
  • react-native: 0.65.1
  • jest: 28.1.2
  • @testing-library/react-native: 10.1.1
  • typescript: 4.5.2

Viewing all articles
Browse latest Browse all 6287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>