Фермент: Как я могу протестировать компонент с побочным эффектом DOM? - PullRequest
0 голосов
/ 08 апреля 2019

Скажем, у меня есть такой компонент -

// @flow

import React, { PureComponent } from 'react';


export default class ReplaceLink extends Component {
  containerRef = React.createRef();

  componentDidMount() {
    const links = 
      Array.from(this.containerRef.current.getElementsByTagName('a'));
    links.forEach(a => a.setAttribute('href', 'dummylink'));
  }

  render = () => <div ref={this.containerRef}>{this.props.children}</div>;
}

, который заменяет ссылки, размещенные внутри него.Но даже когда я выполняю рендеринг с полным домом в энзиме, когда я делаю wrapper.debug(), чтобы увидеть результат рендеринга, я все равно вижу только оригинальные ссылки.

Я пытался сделать форс wrapper.update и использоватьsetTimeouts, но он просто не отражает ожидаемую ссылку.

Ответы [ 2 ]

0 голосов
/ 08 апреля 2019

Найден лучший способ проверить что-то подобное: метод getDOMNode.

  1. Во-первых, убедитесь, что вы используете mount для рендеринга оболочки, поэтому у нас есть смоделированная среда DOM для запроса.

  2. Далее, используйте wrapper.getDOMNode(), чтобы получить базовый узел DOM.

  3. Любые изменения, внесенные во время методов жизненного цикла в базовый DOM, будут отражены в этой ссылке на DOM.
  4. Используйте .querySelector или <insert-dom-query-method>, чтобы сделать утверждения.

    const wrapper = mount(
      <ReplaceLink> 
        <a href="gogole.com"> Google</a> 
      </ReplaceLink>
    );
    
    const linkTags = wrapper.getDOMNode().querySelectorAll('a');
    
    linkTags.forEach(tag => {
      expect(tag.getAttribute('href')).toBe('dummy');
    });
    
0 голосов
/ 08 апреля 2019

Одной из причин, по которой прямой доступ к DOM не рекомендуется в React, является то, что это усложняет тестирование.

Компонент может быть обработан с пропуском componentDidMount:

const wrapper = shallow(<ReplaceLink/>, { disableLifecycleMethods: true })

ТогдаМожно смоделировать ref и componentDidMount можно вызвать вручную:

const setAttribute = jest.fn();
const getElementsByTagName = jest.fn().mockImplementation(() => [{ setAttribute }]);

wrapper.instance().containerRef.current = { getElementsByTagName };
wrapper.instance().componentDidMount();

Затем можно утверждать, что вызванные функции DOM были вызваны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...