When rendering and testing a component with a useEffect that calls an async function that modifies the component's state, then an act() console error will be output when running tests.
@testing-library/react version: 10.0.4jest version: 26.0.1jsdom version: 16.2.2const MyComponent = () => {
const [loaded, setLoaded] = useState(false)
useEffect(() => {
async function load() {
await loadFromApi()
setLoaded(true)
}
load()
}, [])
return loaded ? <div>loaded</div> : <div>loading...</div>
}
// timeout=0 to simulate mocked api responses
const loadFromApi = () => new Promise(resolve => setTimeout(resolve, 0))
Just render this component in a jest test.
test('act() console error', () => {
const sut = render(<MyComponent />)
expect(sut).toBeDefined()
})
This error is output in my project when running tests:
console.error
Warning: An update to null inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
See console output:
https://codesandbox.io/s/react-testing-library-demo-sk2so
Rendering should wait until everything has been resolved.
Since async functions inside useEffect are quite common, rendering a component containing such a hook should wait for the component updates to have finished (with a small timeout).
Hi @fabb,
There's no way for React Testing Library to know that you've got async stuff happening in the background, and you wouldn't want that anyway because you probably want to assert the "loading" state anyway.
This is why React Testing Library gives you async utils which you can use to wait for the UI to update asynchronously.
Here's how you'd fix that codesandbox: https://codesandbox.io/s/react-testing-library-demo-dmklb?file=/src/__tests__/hello.js:244-306
The cool thing about this is the async utils provided by React Testing Library are automatically wrapped in act so you shouldn't ever have to worry about using act manually. Learn more here: https://kcd.im/act-warning
Good luck :)
Thanks for looking into this. I guess I need to find out what I need to wait for. Let鈥榮 go hunting 馃槄
BTW thanks for the tip of updating jest to include a backtrace in the error log output, that helps a lot.
Hi @fabb,
There's no way for React Testing Library to know that you've got async stuff happening in the background, and you wouldn't want that anyway because you probably want to assert the "loading" state anyway.
This is why React Testing Library gives you async utils which you can use to wait for the UI to update asynchronously.
Here's how you'd fix that codesandbox: https://codesandbox.io/s/react-testing-library-demo-dmklb?file=/src/__tests__/hello.js:244-306
The cool thing about this is the async utils provided by React Testing Library are automatically wrapped in
actso you shouldn't ever have to worry about usingactmanually. Learn more here: https://kcd.im/act-warningGood luck :)
OMG I was stuck with this warning for 24 hours. Thank you for your help, this worked.
Most helpful comment
Hi @fabb,
There's no way for React Testing Library to know that you've got async stuff happening in the background, and you wouldn't want that anyway because you probably want to assert the "loading" state anyway.
This is why React Testing Library gives you async utils which you can use to wait for the UI to update asynchronously.
Here's how you'd fix that codesandbox: https://codesandbox.io/s/react-testing-library-demo-dmklb?file=/src/__tests__/hello.js:244-306
The cool thing about this is the async utils provided by React Testing Library are automatically wrapped in
actso you shouldn't ever have to worry about usingactmanually. Learn more here: https://kcd.im/act-warningGood luck :)