In my tests, I would like to block my main thread until one of my components finishes going through its lifecycle methods, through componentDidUpdate()
, after I trigger an event that causes it to add children components to itself. How can I do so?
Something like this:
describe('my <Component />', () => {
it('should do what I want when its button is clicked twice', () => {
const wrapper = mount(<Component />);
const button = wrapper.find('button');
// This next line has some side effects that cause <Component /> to add
// some children components to itself...
button.simulate('click', mockEvent);
// ... so I want to wait for those children to completely go through
// their lifecycle methods ...
wrapper.instance().askReactToBlockUntilTheComponentIsFinishedUpdating();
// ... so that I can be sure React is in the state I want it to be in
// when I further manipulate the <Component />
button.simulate('click', mockEvent);
expect(whatIWant()).to.be.true;
});
});
(I want to do this because, right now, I get this warning:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op.
I believe I'm getting it because my tests cause my component to change its internal state more quickly than React's internal multithreading magic can keep up with, so by the time I i.e. run button.simulate('click')
the second time, React has instantiated the new child components but hasn't finished mounting them yet. I think that waiting for React to finish updating my Component and its children is the best way to solve that problem.)