Mounted wrapper was not wrapped in act(...) warning
See original GitHub issueCurrent behaviour
I have a component that makes use of the useEffect
hook to make an asynchronous call an api (or in the test case a mock of a call to an api) and then call the setState
hook with the result.
I’ve written tests that assert on the outcome of the effect (ie content being returned from the api). I’m using v1.11.2 of the adapter for react-16 my tests pass, snapshots are created and everything appears to be working well, however, a warning is repeatedly logged out from react-dom
.
Here’s the test in question:
it("should render a link block when the api responds with content", () => {
const linkBlockResponse = {
title: "Useful links",
links: [
{
title: "Book a flight",
description: "for your next trip",
image: {
url: "www.someimage.com",
name: "some image"
},
link: {
url: "www.google.com",
name: "google",
target: "_blank",
}
},
{
title: "Gates & Time",
description: "Departures & Arrivals",
image: {
url: "www.someotherimage.com",
name: "some other image"
},
link: {
url: "www.google.com",
name: "google",
target: "_blank",
}
},
]
} as LinkBlock;
const apiResponse = {
content: linkBlockResponse
} as ContentResponse<LinkBlock>;
const apiMock = jest.fn((id: number) => Promise.resolve(apiResponse));
const wrapper = enzyme.mount(<LinkBlockComponent id={1} getLinkBlock={apiMock} />);
return Promise
.resolve(wrapper)
.then(() => {
wrapper.update();
expect(apiMock).toHaveBeenCalledWith(1);
expect(wrapper).toMatchSnapshot();
expect(wrapper.find(LinkBlockHeaderComponent)).toHaveLength(1);
expect(wrapper.find(LinkBlockLinksComponent)).toHaveLength(1);
});
});
Here’s the warning:
console.error node_modules/react-dom/cjs/react-dom.development.js:506
Warning: An update to LinkBlockComponent 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 LinkBlockComponent (created by WrapperComponent)
in WrapperComponent
I’ve attempted wrapping the call to enzyme.mount(<LinkBlockComponent id={1} getLinkBlock={apiMock} />);
in an act block, and asserting afterwards as the warning suggests but this ends up calling all my tests before the component has finished rendering.
I don’t suspect this is an issue caused enzyme or the adapter itself as I’ve noticed that you are wrapping mount calls within an act() block further down, however, I’ve struggled to find any documentation from enzyme on testing the effect of useEffect
.
If you have any suggestions on best practices here or if anything looks amiss, help would be appreciated.
Expected behaviour
Your environment
API
- shallow
- mount
- render
Version
library | version |
---|---|
enzyme | 3.9.0 |
react | 16.8.4 |
react-dom | 16.8.4 |
react-test-renderer | n/a |
adapter (below) | 1.11.2 |
Adapter
- enzyme-adapter-react-16
- enzyme-adapter-react-16.3
- enzyme-adapter-react-16.2
- enzyme-adapter-react-16.1
- enzyme-adapter-react-15
- enzyme-adapter-react-15.4
- enzyme-adapter-react-14
- enzyme-adapter-react-13
- enzyme-adapter-react-helper
- others ( )
Issue Analytics
- State:
- Created 4 years ago
- Reactions:55
- Comments:49 (10 by maintainers)
Using TS-- an even simpler version of @SenP 's solution if you don’t need to interact with the page and don’t want to install waait is this:
Usage:
This is obviously not a good general solution-- looking forward to the general fix
@phattruong-agilityio @mhuconcern @heruifeng1 @ianks
If you’re still running into this issue with
react-apollo
specifically, I got this fixed thanks to a helpful reply on my spectrum post.It seems that when you mount components that include a
query
, you need to await anact
call that pushes the rest of your test to the end of the event loop, even if you don’t need to assert on the updated component after the query.This waait package will help, or you can include the code right in your project, I have these helper functions set up:
Then you can use them in your tests like this:
No more
act(...)
warnings 🎉