Test setTimeout with React Native Testing Library and Jest

Viewed 1424

I have a React Native app with the following Player component that infinitely calls a play() function with a setTimeout. I'm using react-native-testing-library for rendering/testing along with jest.

I am trying to test this setTimeout function. Specifically, I want to spy on the function so that I can expect the setTimeout to have been called any number of times after a given set of seconds. For example, after 3 seconds, the function should have been called 3 times. I am having issues testing this however. My current test looks like this:

fit('displays the content', async () => {
            //jest.useFakeTimers();
          
            const { debug, toJSON, getByText, getByTestId } = render(
                <Player token={'test-token'} saveToken={saveTokenMock} />
            );
            //jest.runOnlyPendingTimers();
            const data = {"device":{"id":58,"updated_at":"2021-07-05T01:39:53.588Z","events":[{"my data here"}]}]}};
            mock.onPost('https://www.mydomain.io/api/v1/devices/events').reply(200, data);

            await waitFor(() => {
                expect(getByTestId('imageAsset')).toBeTruthy();
                expect(toJSON()).toMatchSnapshot()
                
            });
            
})

When I add the jest.useFakeTimers() and jest.runOnlyPendingTimers(), the waitFor function errors with a timeout error. How can I spy on the setTimeout? Here is the general idea of my component:

class Player extends Component {
   componentDidMount(){
       this.play()
    }

   play() {
     //does some things

     setTimeout(play, 1000)
   }
}
1 Answers

You can advance the time using advanceTimersByTime provided by jest. In order to check the number of the function calls, use toHaveBeenCalledTimes.

The provided example in Jest documents is very similar to your component.

Related