title: Mocking out React.Suspense Whilst Leaving the Rest of React Intact
body: <p>I'm trying to write a <a href="https://jestjs.io" rel="nofollow noreferrer">Jest</a> unit test for a component that uses <a href="https://reactjs.org/docs/code-splitting.html#suspense" rel="nofollow noreferrer">React.Suspense</a>.</p>
  
  <p>Simplified versions of my component modules under test:</p>
  
  <p><em>MyComponent.js</em></p>
  
  <pre><code>import React from 'react';
  
  export default () =&gt; &lt;h1&gt;Tadaa!!!&lt;/h1&gt;;
  </code></pre>
  
  <p><em>MySuspendedComponent.js</em></p>
  
  <pre><code>import React, { Suspense } from 'react';
  import MyComponent from './MyComponent';
  
  export default () =&gt; (
      &lt;Suspense fallback={&lt;div&gt;Loading…&lt;/div&gt;}&gt;
          &lt;MyComponent /&gt;
      &lt;/Suspense&gt;
  );
  </code></pre>
  
  <p>Naïvely, in my first attempt, I wrote a unit test that uses <a href="https://airbnb.io/enzyme/" rel="nofollow noreferrer">Enzyme</a> to mount the suspended component:</p>
  
  <p><em>MySuspendedComponent.test.js</em></p>
  
  <pre><code>import React from 'react';
  import { mount } from 'enzyme';
  import MySuspendedComponent from './MySuspendedComponent';
  
  test('the suspended component renders correctly', () =&gt; {
      const wrapper = mount(&lt;MySuspendedComponent /&gt;);
      expect(wrapper.html()).toMatchSnapshot();
  });
  </code></pre>
  
  <p>This causes the test to crash with the error message:</p>
  
  <blockquote>
    <p>Error: Enzyme Internal Error: unknown node with tag 13</p>
  </blockquote>
  
  <p>Searching for the error message on the web, I found that this is most likely caused by Enzyme not being ready to render <code>Suspense</code> (yet).</p>
  
  <p>If I use <code>shallow</code> instead of <code>mount</code>, the error message changes to:</p>
  
  <blockquote>
    <p>Invariant Violation: ReactDOMServer does not yet support Suspense</p>
  </blockquote>
  
  <p>My next attempt was to mock out <code>Suspense</code> with a dummy pass-through component, like this:</p>
  
  <p><em>MySuspendedComponent.test.js</em></p>
  
  <pre><code>import React from 'react';
  import { mount } from 'enzyme';
  import MySuspendedComponent from './MySuspendedComponent';
  
  jest.mock('react', () =&gt; {
      const react = require.requireActual('react');
      return () =&gt; ({
          ...react,
          Suspense({ children }) {
              return children;
          }
      });
  });
  
  test('the suspended component renders correctly', () =&gt; {
      const wrapper = mount(&lt;MySuspendedComponent /&gt;);
      expect(wrapper.html()).toMatchSnapshot();
  });
  </code></pre>
  
  <p>The idea is to have a mock implementation of the React module that contains all the actual code from the React library, with only <code>Suspense</code> being replaced by a mock function.</p>
  
  <p>I've used this pattern with <code>requireActual</code>, as described in the <a href="https://jestjs.io/docs/en/bypassing-module-mocks" rel="nofollow noreferrer">Jest documentation</a>, successfully in other unit tests when mocking other modules than React, but with React, it does not work.</p>
  
  <p>The error I get now is:</p>
  
  <blockquote>
    <p>TypeError: (($_$w(...) , <em>react) || ($</em>$w(...) , _load_react(...))).default.createElement is not a function</p>
  </blockquote>
  
  <p>…which, I assume, is caused by the original implementation of React not being available after my mocking trick.</p>
  
  <p><strong>How can I mock out Suspense while leaving the rest of the React library intact?</strong></p>
  
  <p>Or is there another, better way to test suspended components?</p>