I have to components imported with the new React lazy
API (16.6).
import React, {PureComponent, lazy} from 'react'; const Component1 = lazy(() => import('./Component1')); const Component2 = lazy(() => import('./Component2')); class CustomComponent extends PureComponent { ... render() { return ( <div> <Component1 /> <Component2 /> </div> ); } }
In my tests, I’m doing the snapshots of this component. It’s a very straightforward test:
import { create } from 'react-test-renderer'; const tree = await create(<CustomComponent />).toJSON(); expect(tree).toMatchSnapshot();
In the logs, the test is failing with this error:
A React component suspended while rendering, but no fallback UI was specified. Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.
Do I have to wrap in every single test suite with <Suspense>...
?
it('should show the component', async () => { const component = await create( <React.Suspense fallback={<div>loading</div>}> <CustomComponent /> </React.Suspense> ); const tree = component.toJSON(); expect(tree).toMatchSnapshot(); };
If I do that, I only see in the snapshot the fallback
component.
+ Array [ + <div> + loading + </div>, + ]
So, which is the best way to do it?
Advertisement
Answer
Do I have to wrap in every single test suite with <Suspense>
?
Yes, the
Suspense
component is neccessary for lazily loading child components, particularly providing a fallback and for reconciliation when the lazy components are available.
Export Component1
and Component2
in CustomComponent
so that they can be imported in tests.
import React, {PureComponent, lazy} from 'react'; export const Component1 = lazy(() => import('./Component1')); export const Component2 = lazy(() => import('./Component2')); export default class CustomComponent extends PureComponent { //... }
Remember that the lazy loaded components are promise-like. Import them in the test, and wait for them to resolve before doing a check that the snapshot matches.
import { create } from 'react-test-renderer'; import React, {Suspense} from 'react'; import CustomComponent, {Component1, Component2} from './LazyComponent'; describe('CustomComponent', () => { it('rendered lazily', async()=> { const root = create( <Suspense fallback={<div>loading...</div>}> <CustomComponent/> </Suspense> ); await Component1; await Component2; expect(root).toMatchSnapshot(); }) })