mardi 25 février 2020

React test Error: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'

I have this file

import React, { RefObject } from 'react';

interface Props {
  domNodeId: string;
}

export default class Portal extends React.Component<Props> {
  elementRef: RefObject<HTMLDivElement> = React.createRef();

  componentDidMount() {
    const { domNodeId } = this.props;

    if (document.getElementById(domNodeId)) {
      document.getElementById(domNodeId).appendChild(this.elementRef.current);
    }
  }

  componentDidUpdate(prevProps) {
    const { domNodeId } = this.props;

    if (prevProps.domNodeId !== domNodeId && document.getElementById(domNodeId)) {
      const domNodeIdElement = document.getElementById(domNodeId);
      while (domNodeIdElement.firstChild) {
        domNodeIdElement.removeChild(domNodeIdElement.firstChild);
      }

      document.getElementById(domNodeId).appendChild(this.elementRef.current);
    }
  }

  render() {
    const { domNodeId } = this.props;

    return (
      <>
        {domNodeId && (
          <div className="portal" ref={this.elementRef}>
            {this.props.children}
          </div>
        )}
      </>
    );
  }
}

And my test file is

import { shallow } from 'enzyme';
import { mount } from 'enzyme';
import Portal from '~/portal';

const props = {
  domNodeId: 'domNodeId'
};


describe('<Portal />', () => {
beforeAll(() => {
    const div = document.createElement('div');
    div.setAttribute('id', 'domNodeId');
    div.innerHTML = '<div></div>';
    document.body.appendChild(div);
    });

  it('matches snapshot', () => {
    const tree = renderer.create(<Portal {...props} />).toJSON();

    expect(tree).toMatchSnapshot();
  });



  it('triggers componentDidUpdate', () => {
    const wrapper = shallow(<Portal {...props} />) as any;
    wrapper.setProps({ domNodeId: 'newdomNodeId' });
    const tree = renderer.create(<Portal {...props} />).toJSON();

    expect(tree).toMatchSnapshot();
  });

  it('componentWillUnmount should be called on unmount', () => {
    const component = shallow(<Portal {...props} />) as any;
    const componentWillUnmount = jest.spyOn(component.instance(), 'componentWillUnmount');
    component.unmount();
    expect(componentWillUnmount).toHaveBeenCalled();
  });

  it('componentWillUnmount will remove the portal', () => {
    const window = {
      document: {
        body: {
          removeChild: jest.fn()
        }
      }
    };
  const wrapper = shallow(<Portal {...props} />) as any;
  wrapper.setProps({ domNodeId: 'newdomNodeId' });
  });

I need to get 100% coverage on my tests files but I get the following error Error: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'

How can I mock the react reference so as to be and HTML Div element? I think that only then I won't get this error. Or should I use the expect function to check if the code works properly?

Do you have any other suggestion?

Aucun commentaire:

Enregistrer un commentaire