I have a useEffect hook that loads when the component is mounted, as so:
useEffect(() => {
listFiles().then(keys => {
setKeys(keys)
console.log(keys)
}).catch(err => {
showFail(err.message)
})
}, [])
I'm trying to test the function with react testing-library, simply using the render function:
beforeEach(() => {
render(<Dashboard />)
})
However, when I run any test that resolves the promise and sets the state:
jest.mock('../utils/storage', () => ({
listFiles: jest.fn(() => Promise.resolve([])),
}))
I end up with a weird warning message about using act
to to wrap the event:
Warning: An update to Dashboard 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 ..
in Dashboard
18 | useEffect(() => {
19 | listFiles().then(keys => {
> 20 | setKeys(keys)
| ^
21 | console.log(keys)
22 | }).catch(err => {
23 | showFail(err.message)
I have tried wrapping the render in an act
, but it doesn't seem to change anything.
Any suggestions as to what I'm doing wrong here? Should I be rendering in some other way?
Thanks in advance!
This error usually happens when you try to assert before the component has finished updating all state.
Note that inside listFiles
you are calling setKeys(keys)
and that updates the state.
You should await
for the new keys(or files) to show up in the document:
expect(await findByText('some file name or key')).toBeInTheDocument();
// more asserts here
Alternatively, you can waitFor the mock to have been called (although I think the option above is better).
await waitFor(() => expect(listFilesMock).toHaveBeenCalled());
// more asserts here
The methods above should already be wrapped in act
for you by the React Testing Library, so you don't need to do it
act()
from the React docs:When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. React provides a helper called act() that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions.
The name act comes from the Arrange-Act-Assert pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With