Search code examples
reactjswebpackbabeljsjestjsnext.js

How to unit test Next.js dynamic components?


The Next.js dynamic() HOC components aren't really straightforward to tests. I have 2 issues right now;

  • First jest is failing to compile dynamic imports properly (require.resolveWeak is not a function - seems to be added by next babel plugin)
  • Second I can't get good coverage of the modules logic; looks like it's simply not run when trying to render a dynamic component.

Solution

  • Let's assume we have a component like this (using a dynamic import):

    import dynamic from 'next/dynamic';
    
    const ReactSelectNoSSR = dynamic(() => import('../components/select'), {
        loading: () => <Input />,
        ssr: false
    });
    
    export default () => (
        <>
            <Header />
            <ReactSelectNoSSR />
            <Footer />
        </>
    );
    

    The dynamic import support offered by Next.js does not expose a way to preload the dynamically imported components in Jest’s environment. However, thanks to jest-next-dynamic, we can render the full component tree instead of the loading placeholder.

    You'll need to add babel-plugin-dynamic-import-node to your .babelrc like so.

    {
      "plugins": ["babel-plugin-dynamic-import-node"]
    }
    

    Then, you can use preloadAll() to render the component instead of the loading placeholder.

    import preloadAll from 'jest-next-dynamic';
    import ReactSelect from './select';
    
    beforeAll(async () => {
        await preloadAll();
    });
    

    📝 Source