title: How to test state update and component rerender after async call in react
body: <p>I am writing an simple app where after clicking the button, async call to spotify API should be performed and when promise resolves it should update component's state. I am using react hooks to manage state in my component.</p>
  
  <p>In my tests I mocked API call.</p>
  
  <p>spotify.jsx</p>
  
  <pre><code>export default class Spotify {
    constructor(token) {
      this.axiosInstance = axios.create({
        baseURL: baseURL,
        headers: buildHeaders(token),
      });
    }
  
    async getUserInfo() {
      const userInfo = await this.axiosInstance({
        url: `/me`,
      });
      return userInfo.data
    }
  }
  
  </code></pre>
  
  <p>spotify mock:</p>
  
  <pre><code>const getUserInfoMock = jest.fn();
  
  const mock = jest.fn().mockImplementation(() =&gt; ({
    getUserInfo: getUserInfoMock,
  }));
  
  export default mock;
  </code></pre>
  
  <p>User.jsx</p>
  
  <pre><code>const User = props =&gt; {
    const [user, setUser] = useState(null);
    const {token} = useContext(AuthContext);
    const spotify = useMemo(() =&gt; new Spotify(token), [token]);
  
    const getUserInfo = async () =&gt; {
      console.log("button clicked")
      const fetched = await spotify.getUserInfo();
      console.log(fetched)
      setUser(fetched);
    }
  
    return (
      &lt;React.Fragment&gt;
        &lt;p&gt;user page&lt;/p&gt;
        &lt;button onClick={getUserInfo} &gt; click me &lt;/button&gt;
        {user &amp;&amp; (
          &lt;div&gt;
            &lt;p&gt;{user.display_name}&lt;/p&gt;
            &lt;p&gt;{user.email}&lt;/p&gt;
          &lt;/div&gt;
        )}
      &lt;/React.Fragment&gt;
    );
  };
  </code></pre>
  
  <p>My question is how to properly test such behavior. I managed to make it pass but isn't calling <code>await</code> on <code>simulate()</code> an ugly hack? Simulate does not return a promise. Here is a test:</p>
  
  <pre><code>  it('updates display info with data from api', async () =&gt; {
      const userInfo = {
        display_name: 'Bob',
        email: 'bob@bob.bob',
      };
      spotifyMock.getUserInfo.mockImplementation(() =&gt; Promise.resolve(userInfo));
  
      wrapper = mount(&lt;User /&gt;);
      expect(wrapper.find('p')).toHaveLength(1);
      await wrapper
        .find('button')
        .last()
        .simulate('click');
  
      wrapper.update();
      expect(wrapper.find('p')).toHaveLength(3);
    });
  </code></pre>
  
  <p>On the other hand when i check only if mock was called I don't need to use async/await and test passes:</p>
  
  <pre><code>  it('calls spotify api on click', () =&gt; {
      wrapper = mount(&lt;User /&gt;);
      expect(spotifyMock.getUserInfo).not.toHaveBeenCalled();
      wrapper
        .find('button')
        .last()
        .simulate('click');
      expect(spotifyMock.getUserInfo).toHaveBeenCalledTimes(1);
    });
  
  </code></pre>
  
  <p>I wonder if my way of testing is proper and what if I want to add a feature to fetch data from api when component renders - with useEffect hook. Does Enzyme has a full support for react hooks?
  I also struggle with warning <code>Warning: An update to User inside a test was not wrapped in act(...)</code> even if I wrap a <code>mount</code> and <code>simulate</code> functions.</p>