Testing with React's Jest and Enzyme when async componentDidMount
19,922
Solution 1
Solution:
1: use the async/await syntax.
2: Use mount (no shallow).
3: await async componentLifecycle.
For ex:
test(' ',async () => {
const wrapper = mount(
<Foo />
);
await wrapper.instance().componentDidMount();
})
Solution 2
Something like this should work for you:-
describe('...', () => {
test('...', async () => {
const wrapper = await mount(<Foo/>);
expect(wrapper.instance().bar).toBe(100);
});
});
Solution 3
Try this:
it('should do something', async function() {
const wrapper = shallow(<Foo />);
await wrapper.instance().componentDidMount();
app.update();
expect(wrapper.instance().bar).toBe(100);
});
Solution 4
None of the solutions provided here fixed all my issues. At the end I found https://medium.com/@lucksp_22012/jest-enzyme-react-testing-with-async-componentdidmount-7c4c99e77d2d which fixed my problems.
Summary
function flushPromises() {
return new Promise(resolve => setImmediate(resolve));
}
it('should do someting', async () => {
const wrapper = await mount(<Foo/>);
await flushPromises();
expect(wrapper.instance().bar).toBe(100);
});
Author by
Whj
Updated on June 24, 2022Comments
-
Whj almost 2 years
- react:16.3.0-alpha.1
- jest: "22.3.0"
- enzyme: 3.3.0
- typescript: 2.7.1
code:
class Foo extends React.PureComponent<undefined,undefined>{ bar:number; async componentDidMount() { this.bar = 0; let echarts = await import('echarts'); // async import this.bar = 100; } }
test:
describe('...', () => { test('...', async () => { const wrapper = shallow(<Foo/>); const instance = await wrapper.instance(); expect(instance.bar).toBe(100); }); });
Error:
Expected value to be: 100 Received: 0
-
Ignacio about 6 yearsedited, have you tried the await when you execute the instance?, The await basically operates on a promise
-
Ignacio about 6 yearsif you can share your complete test
-
VivekN about 6 yearsThis is not what you were trying to check in your question posted above.My answer is the right solution to your problem.
-
Simon Keep almost 6 yearsThis was the best solution for me, particularly as I didn't want to shallow mount
-
Max over 5 yearsAfter looking through google on this problem and trying to implement async componentDidMount through mount's enzyme. And "mount" way is not fit for react native project - I had a lot mistakes. This method helped me. And you don't need to install jsdom and use mount. "react": "16.4.1", "react-native": "0.56.0", "enzyme": "^3.4.4", "jest": "23.5.0"
-
Pavan over 5 yearswhat's app here?
-
MustSeeMelons over 5 yearsThis will cause the method to run twice.
-
cameck over 5 yearsI don't think
.instance()
returns a promise, so I don't thinkawait
is doing anything there.TypeError: wrapper.instance(...).then is not a function
-
cameck over 5 years@Pavan I think
wrapper.update()
was intended. --ref -
cameck over 5 yearsbtw,
await
won't do anything there unless yourcomponentDidMount()
returns a promise -
Marius about 5 years@VivekN has the right solution. This will run "componentDidMount" twice. Any await after mounting will probably "solve" the problem, but it's not the right solution in my opinion.
-
Yann Dìnendal almost 5 yearsIndeed; and if you have a
setState
in the component'sdidMount
, you'll need to addwrapper.update();
before theexpect
.