title: JS unit testing using enzyme: how to wait for setState within component's method to finish before proceeding with test case
body: <p>I have a component <code>MyComponent</code> with method <code>doSomething</code> that updates a state, and <code>renderChildren</code> that renders child components based on these states:</p>
  
  <pre><code>class MyComponent extends Component {
    constructor(props) {
      super(props);
      ...
      this.state = {
        renderChildA: true,
        renderChildB: false,
      };
    }
  
    doSomething = (params) =&gt; {
      // Do something...
  
      this.setState({ 
        renderChildA: false,
        renderChildB: true,
      });
    }
  
    renderChildren = () =&gt; {
      const { renderChildA, renderChildB } = this.state;
      if (renderChildA) {
        return &lt;ChildComponentA /&gt;;
      } else if (renderChildB) {
        return &lt;ChildComponentB /&gt;;
      }
    }
  
    render() {
      return (
        &lt;div&gt;
          {this.renderChildren()}
          ...
        &lt;/div&gt;
      );
    }
  }
  </code></pre>
  
  <p><em>NOTE: the component is also connected to Redux, but has been simplified.</em></p>
  
  <p>For unit testing, I'm calling <code>doSomething</code> and verifying that <code>ChildComponentB</code> is visible:</p>
  
  <pre><code>test('doSomething should trigger ChildComponentB to pop up', () =&gt; {
    const wrapper = shallow(
      &lt;MyComponent
      ...
      /&gt;,
    ).dive();
  
    wrapper.instane().doSomething(params); // assume params is defined
  
    const childComponentB = wrapper.find('ChildComponentB');
    expect(childComponentB).toHaveLength(1);
  });
  </code></pre>
  
  <p>However, the test case above fails:</p>
  
  <pre><code>my-component.test.jsx &gt; Some test group name &gt; doSomething should trigger ChildComponentB to pop up
  
      expect(received).toHaveLength(length)
  
      Expected value to have length:
        1
      Received:
        // Some giant JSON object
      recevied.length:
        0
  
        xxx |    const childComponentB = wrapper.find('ChildComponentB');
        xxx |    expect(childComponentB).toHaveLength(1);
        xxx |  });
  </code></pre>
  
  <p>Based on the logging, I'm seeing that <code>setState</code> within <code>doSomething</code> is triggered after <code>expect</code> statement in the test case. I suspect this is happening since <a href="https://stackoverflow.com/questions/36085726/why-is-setstate-in-reactjs-async-instead-of-sync"><code>setState</code> is asynchronous</a>, but I don't know a workaround for this (other than <code>setTimeout</code>).</p>