await userEvent.type causes setState in async effect warns not wrapped in act(...)
See original GitHub issue@testing-library/user-event
version: 12.1.0- Testing Framework and version: jest
- DOM Environment: jsdom
Relevant code or config
// App.js
import React, {useState, useEffect} from "react";
import "./styles.css";
export default function App() {
const [value, setValue] = useState('')
const [content, setContent] = useState('')
useEffect(() => {
Promise.resolve(value).then(setContent)
}, [value])
return (
<div className="App">
<div>{content}</div>
<input placeholder="input" value={value} onChange={({target: {value}}) => setValue(value)}/>
</div>
);
}
// App.test.js
import React from 'react'
import {render, screen} from '@testing-library/react'
import App from './App'
import userEvent from '@testing-library/user-event'
test('waining', async () => {
render(<App/>)
await userEvent.type(screen.getByPlaceholderText('input'), 'abc')
expect(screen.getByText('abc')).toBeTruthy()
})
What you did:
testing a compoent with setState in async useEffect
What happened:
test passes with a waning of not wrapped in act(...)
Warning: An update to App inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://fb.me/react-wrap-tests-with-act
in App (at App.test.js:15)
Reproduction repository:
codesandbox demo: https://codesandbox.io/s/heuristic-chaum-v50nn?file=/src/App.test.js
Problem description:
When await userEvent.type which triggers an async effect to setState another state, the test passes, but a warning of not wrapped in act(...)
happens.
If not await userEvent.type, but use waitFor to assert, no warning happens:
// this test passes
test('pass', async () => {
render(<App/>)
userEvent.type(screen.getByPlaceholderText('input'), "abc")
await waitFor(() => {
expect(screen.getByText('abc')).toBeTruthy()
})
})
Suggested solution:
I’m not very understand what act
is doing, and not sure if this is a bug or expected behavior.
If it’s a bug, the warning should not happen.
If it’s expected, this case should be documented. It’s very confusing to see the warning.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (4 by maintainers)
Top GitHub Comments
Just for info
type
’s promise is always resolved immediately except when you passdelay
parameterHi, @kentcdodds
What confused me was since userEvent.type return a promise, so I should always await it. But now it seems await is not good for all cases. So I think it should be documented to remind users about it.