I'm trying to run the following test using the built-in react-scripts test
script in create-react-app
:
Timer.test.js
render(<Timer />)
const pauseButton = screen.getByText('pause')
const timerOutput = screen.getAllByRole('heading')[1]
describe('Timer', () => {
test('renders Timer component', () => {
expect(screen.getByText(/session/i)).toBeInTheDocument()
expect(screen.getByText(/25/)).toBeInTheDocument()
})
test('counts down when unpaused', async () => {
jest.useFakeTimers()
fireEvent.click(pauseButton)
setTimeout(
fireEvent.click(pauseButton),
1125
)
jest.runAllTimers()
expect(timerOutput).toHaveTextContent('24:59')
})
})
Jest seems to be working fine until it gets to jest.runAllTimers()
, when I get the following error:
TypeError: callback.apply is not a function
23 | 1125
24 | )
> 25 | jest.runAllTimers()
| ^
26 | expect(timerOutput).toHaveTextContent('24:59')
27 | })
28 |
at node_modules/@jest/fake-timers/build/jestFakeTimers.js:524:25
at callback (node_modules/@jest/fake-timers/build/jestFakeTimers.js:516:29)
at FakeTimers._runTimerHandle (node_modules/@jest/fake-timers/build/jestFakeTimers.js:560:9)
at FakeTimers.runAllTimers (node_modules/@jest/fake-timers/build/jestFakeTimers.js:193:12)
at Object.<anonymous> (src/features/Timer.test.js:25:10)
I have no idea what's going on. Why won't it finish running the test?
The error you're getting is probably because of setTimeout
usage. setTimeout
accepts a function as first argument but you are giving it whatever the return type of fireEvent.click(pauseButton)
. Change the code to:
test('counts down when unpaused', async () => {
jest.useFakeTimers();
fireEvent.click(pauseButton)
setTimeout(() => fireEvent.click(pauseButton), 1125);
// ^ NOTE HERE
jest.runAllTimers();
expect(timerOutput).toHaveTextContent('24:59');
})