Реактивный тест Ошибка: не удалось выполнить appendChild на узле: параметр 1 не относится к типу узла - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть этот файл

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>
        )}
      </>
    );
  }
}

И мой тестовый файл

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' });
  });

Мне нужно 100% покрытие моих тестовых файлов, но я получаю следующую ошибку Error: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'

Как можно смоделировать эталонную реакцию, чтобы быть и HTML Элемент Div? Я думаю, что только тогда я не получу эту ошибку. Или я должен использовать функцию ожидаемого, чтобы проверить, правильно ли работает код?

Есть ли у вас какие-либо другие предложения?

1 Ответ

0 голосов
/ 27 февраля 2020

Я понял это, посмеявшись над getElementById. Код следующий:

    window.document.getElementById = jest.fn(() => ({
      appendChild: jest.fn(),
      removeChild: jest.fn()
    }));

И тогда я могу запустить свой снимок, как показано ниже:

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

    expect(window.document.getElementById).toBeCalled();
    expect(tree).toMatchSnapshot();
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...