Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest/Enzyme Class Component testing with React Suspense and React.lazy child component

So I converted an import used in a class component to React.lazy import api and wrapped it in a Suspense tag. When I test that class component, enzyme throws an error "Enzyme Internal Error: unknown node with tag 13". Is there a way to render and test the mount of the lazy loaded component rather than using shallow render?

I've already tried async await to wait until the promise of the lazy load resolved but that didn't work neither, like so:

it('async await mount', () async () => {
  const wrapper = await mount(<Component />)
}

here's example code:

Component.js

import React, { PureComponent, Suspense } from 'react'

const ChildComponent = React.lazy(() => import('../ChildComponent'))

export default class Component extends PureComponent {
  constructor() {
      super()
      this.state = {
          example: null
      }
  }

  doSomething = () => this.setState({
      example: 'example'
  })

  render() {
    return (
      <div>
        <p>Example</p>
        <Suspense fallback={<div>...loading</div>}>
            <ChildComponent 
               example={this.state.example}
               doSomething={this.doSomething}
            />
        </Suspense>
      </div>
    )
  }
}

Component.test.js

import React from 'react'
import renderer from 'react-test-renderer'
import { mount } from 'enzyme'
import Component from '../../Component'

describe('Component', () => {
    // snapshot renders loading and not children
    it('example snapshot of tree', () => {
        const tree = renderer.create(<Component />).toJSON()
        expect(tree).toMatchSnapshot()
    })

    it('example mount test', () => {
        // this test fails and throws error I state above
        const wrapper = mount(<Component />)
        wrapper.setState({ example: 'example' })
        expect(wrapper.state.example).toBe('example')
    })
})

I read that Enzyme does not support React 16.6 Suspense API yet but I wanted to know if there was still a way to test the mounted so I can use things like simulate and find API from Enzyme.

like image 205
Ruben Avatar asked Dec 13 '18 19:12

Ruben


People also ask

How do you test the react lazy component?

You can use @testing-library/react to test the React. lazy() method. In addition, if the lazy-loaded component is too complex and you only want to test the parent component that contains the component, you can use the jest. mock() method To provide a mocked version of the subcomponent.

What is difference between Jest and Enzyme and react testing library?

Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only.

Does react lazy require suspense?

Suspense is a component required by the lazy function basically used to wrap lazy components. Multiple lazy components can be wrapped with the suspense component. It takes a fallback property that accepts the react elements you want to render as the lazy component is being loaded.

Which is better Enzyme or Jest?

Shallow rendering is one way that Enzyme keeps tests simpler than Jest. When you shallow-render a component with Enzyme, you render only that component. Enzyme doesn't render any of the children of that component. This is a useful restriction that ensures that you aren't testing too much in one test.


1 Answers

Solution

The GitHub issue linked by ChuckJHardy has been resolved merged and released. You are now able to use the mount API in enzyme as of 1.14.0.

References

https://github.com/airbnb/enzyme/pull/1975

like image 189
pygeek Avatar answered Sep 22 '22 11:09

pygeek