You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The component being tested should update a useState() within a setTimeout() in response to user input
The test should use Fake Timers, perform that user input, then verify the results of the useState() change (e.g. querying for an element that should now be rendered)
In my linked repro, this test will fail unless the "user input" done by the test happens in an act()
So, within the linked sandbox:
Run pnpm test, the test will fail
Tweak MyForm.test.js and uncomment the act(...) call. Running pnpm test will now succeed.
Expected behavior
The test should pass without needing to wrap the user input in act(...), because according to this comment:
No, wrapping with act is neither required nor recommended.
Actual behavior
If the user input isn't wrapped in act(...), then, even though the useState() value was updated, a re-render isn't triggered before the test continues, causing it to fail.
A similar issue I encountered where the test was passing when it should fail.
App.jsx
functionApp(){const[counter,setCounter]=useState(0);return(<buttontype="button"// The next line should make the test failonClick={()=>setCounter(counter+1)}>{counter}</button>);}
App.test.jsx
it('should increment a counter',async()=>{constuser=userEvent.setup();render(<App/>);constbutton=screen.getByRole('button');// await act(async () => {awaituser.tripleClick(button);// });expect(button).toHaveTextContent('3');});
If the clicks are ever called really close to each other, it is possible that useState might use stale data. Hence, I was expecting it to catch the bug on its own since it's discouraged to wrap with act(...) according to the docs.
But unexpectedly, the test passes unless you wrap the tripleClick event with act(...).
Reproduction example
https://codesandbox.io/p/devbox/9r8lr2
Prerequisites
useState()
within asetTimeout()
in response to user inputuseState()
change (e.g. querying for an element that should now be rendered)In my linked repro, this test will fail unless the "user input" done by the test happens in an
act()
So, within the linked sandbox:
pnpm test
, the test will failMyForm.test.js
and uncomment theact(...)
call. Runningpnpm test
will now succeed.Expected behavior
The test should pass without needing to wrap the user input in
act(...)
, because according to this comment:Actual behavior
If the user input isn't wrapped in
act(...)
, then, even though theuseState()
value was updated, a re-render isn't triggered before the test continues, causing it to fail.User-event version
14.5.2
Environment
Repro'd in a sandbox even though it's a bit tricky these days 😅
Additional context
No response
The text was updated successfully, but these errors were encountered: