Энзим: как я могу протестировать компонент с побочным эффектом DOM?

#reactjs #jestjs #enzyme

#reactjs #jestjs #энзим

Вопрос:

Допустим, у меня есть такой компонент —

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

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

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

Ответ №1:

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

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

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

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

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

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

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

Ответ №2:

Найден лучший способ протестировать что-то подобное с помощью 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');
    });