#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
метода.
-
Во-первых, обязательно используйте
mount
для рендеринга оболочки, чтобы у нас была смоделированная среда DOM для запроса. -
Затем используйте
wrapper.getDOMNode()
, чтобы получить базовый узел DOM. - Любые изменения, внесенные во время методов жизненного цикла в базовый DOM, будут отражены в этой ссылке на DOM.
-
Используйте
.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'); });