render(view) let timerCellsList; await waitFor(() => { lockCellsList = screen.getAllByTestId('TimerCell'); expect(lockCellsList).toHaveLength(2); }); const startTimerButton = within(timerCellsList[1]).getByRole('button'); userEvent.click(startTimerButton); await waitFor(() => {}, {timeout: 0}); // 测试通过了,没有这行就失败了。 // 我可以设置超时时间为任意数字,包括0。 const activeTimer = await screen.findByRole('cell', {name: /00:00/i}); expect(activeTimer).toBeInTheDocument();
I wrote a test where the user clicks a button. The button sends a network request, and if 200 is returned, a timer is displayed and starts counting in seconds. I'm using MSW to return a mock response. Since the network request is obviously asynchronous, I search for this timer by waiting for screen.findByRole to be called. The problem I'm having is that it only works after calling userEvent.click(startTimerButton)
and calling await screen.findByRole('cell', {name: /00:00/i})
The test can pass only when await waitFor(() => {})
is called. It seems that this test only passes if I let it sleep for a while before searching for the timer. I don't understand why I can't start the search timer immediately.
Without the waitFor statement, the error message I get is:
Error: Throws: "Test timeout exceeded 5000 milliseconds. If this is a long running test, use jest.setTimeout(newTimeout) to increase the timeout value. " var evt = document.createEvent('event'); TypeError: Cannot read property 'createEvent' of null
Does anyone know the reason? I wish I didn't have to go around it like I do now.
I also tried changing my await findBy to a getBy wrapped inside a waitFor statement, but that didn't work either. It seems like I just need to let it sleep for a while and then start searching.
P粉2486022982023-09-10 10:14:46
You are missing await
in this line:
userEvent.click(startTimerButton);
So give it a try:
await userEvent.click(startTimerButton);
As of version 14, the userEvent
API is asynchronous.