javascriptreactjsreact-loadablereact-testing-library

Testing react-loadable components


I'm having trouble testing my React components that use react-loadable. Say, I have a Button component that, depending on whether it receives an icon prop, loads an Icon component like so:

Button.js

const LoadableIcon =  Loadable({
  loader: () => import('./Icon'),
  loading: () => <div>Loading...</div>
})

function Button(props) {
  return (
    <button 
      onClick={props.onClick}>
      {props.icon &&
        <LoadableIcon name={props.icon} />}
      {props.children}
    </button>
  )
}

When I test this component, however, the Icon had not loaded yet, and instead the test only finds the <div>Loading...</div> element...

Button.test.js

import React from 'react'
import {render} from 'react-testing-library'

import Button from '../Button'


describe('Button', () => {
  it('renders icon correctly', () => {
    const {getByText} = render(
      <Button 
        icon='add' 
      />
    )
    expect(getByText('add')).toBeInTheDocument()
  })
}) 

Is there an elegant way to handle this situation without using actual setTimeouts?


Solution

  • So, the answer is to read the docs - note to self! The solution based on docs was the following:

    describe('Button', () => {
      it('renders icon correctly', async () => {
        const {getByText} = render(
          <Button 
            icon='add' 
          />
        )
        const icon = await waitForElement(() => getByText('add'))
        expect(icon).toBeInTheDocument()
      })
    })
    

    Also, note that async needs to be used together with await.