This minimum working example demonstrates what happens in a smaller test scenario:
src/code.test.js
:
import {useState, useEffect, useCallback} from 'react';
import {render, waitForElementToBeRemoved, fireEvent} from '@testing-library/react';
global.fetch=url=>Promise.resolve({json: ()=>{
return Promise.resolve('test');
}});
const Component = ({callback}) => {
const [serverData, setServerData] = useState(null);
useEffect(()=>{
fetch('/api/get_it').then(r=>r.json()).then(data=>{
setServerData(data);
});
}, []);
if (!callback) {
return <div>No Callback</div>;
}
return <div>Server data: {serverData}</div>;
}
test('without callback', async () => {
const component = render(<Component/>);
component.getByText('No Callback');
});
package.json
:
{
"dependencies": {
"@testing-library/react": "^13.3.0",
"react-scripts": "5.0.1"
},
"scripts": {
"test": "react-scripts test --verbose",
"check": "jest --version"
}
}
When running this (npm i && npm test;
), I get
Warning: An update to Component inside a test was not wrapped in act(...).
...
7 |
8 | const Component = ({callback}) => {
> 9 | const [serverData, setServerData] = useState(null);
| ^
10 |
This is because of the setServerData
call after the fetch
on line 12 is resolved. In this test case, with the missing callback
, I don't care about the serverData
. The naive approach to fixing this would be to add callback
to the dependency array for the useEffect
on line 15. That is not acceptable because that useEffect
should not run again any time callback
changes!
How to solve the "update was not wrapped in act()" warning in testing-library-react? is materially different from that question because in this question, in my code there is nothing to find.
How can I write this test to avoid this warning?