How to wait until setState in a DidMount component resolves when tested by an enzyme?

I am trying to test a React component that runs some asynchronous code and calls setState in a DidMount component.

Here is my reaction component that I want to test:

/**
*
* AsyncComponent
*
*/

import React from 'react';

class AsyncComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false,
      component: null,
    };
  }
  componentDidMount() {
    this.props.component.then(component => {
       this.setState({
         loaded: true,
         component: component.default ? component.default : component,
       });
    });
  }
  render() {
    if (!this.state.loaded) {
      return null;
    }

    const Component = this.state.component;

    const { component, ...rest } = this.props;

    return <Component {...rest} />;
  }
}

export default AsyncComponent;

Here is a test case. I use jester and enzyme.

import React from 'react';
import { mount } from 'enzyme';

import AsyncComponent from '../index';

const TestComponent = () => <div>Hello</div>;

describe('<AsyncComponent />', () => {
  it('Should render loaded component.', () => {
    const promise = Promise.resolve(TestComponent);
    const rendered = mount(<AsyncComponent component={promise} />);
    expect(rendered.state().loaded).toBe(true);
  });
});

The test failed because state.loaded is still set to false. Is there a way to make sure that AsyncComponent is fully loaded before the call?

I can make it work if I wrap the wait statement in setTimeout, but this seems like a pretty hacky way to do it. How should I do it?

+4
source share
2 answers

, - , DidMount, , ,

const loadFiltersTree = jest.fn()   
const wrapper = shallow(<FilterTree loadFiltersTree={loadFiltersTree} />)
jest.useFakeTimers()
jest.runAllTimers()
setImmediate(() => {
  expect(loadFiltersTree.mock.calls.length).toEqual(1)
})
0

async/await, , docs

describe('<AsyncComponent />', () => {
  it('Should render loaded component.', async() => {
    const promise = Promise.resolve(TestComponent);
    const rendered = mount(<AsyncComponent component={promise} />);
    await promise
    expect(rendered.state().loaded).toBe(true);
  });
});
-1

Source: https://habr.com/ru/post/1678759/


All Articles