Уточнение сообщения об ошибке
Использование mount
, как в примере кода выше, дает эту ошибку:
TypeError: _reactDom2.default.findDOMNode(...).scrollIntoView is not a function
Использование shallow
дает ошибку, указанную выше:
TypeError: Cannot read property 'scrollIntoView' of null
неглубоко
Выпуск
shallow
не выполняет DOM-рендеринг, поэтому никогда не будет DOM-узла для вызова scrollIntoView()
.
Решение
Любой код, который выполняет манипуляции с DOM, должен быть протестирован с использованием полного рендеринга DOM, предоставленного mount
.
крепление
"Средой по умолчанию в Jest является среда, подобная браузеру через jsdom" .
"jsdom
- это реализация многих веб-стандартов на чистом JavaScript ... [которые] эмулируют [под] достаточное количество подмножеств веб-браузера, чтобы быть полезными для тестирования" .
Выпуск
jsdom
реализует большую часть среды браузера, но не все. Особо следует отметить, что этот вопрос не реализует scrollIntoView
, поскольку jsdom
не выполняет компоновку и, следовательно, не сможет обеспечить точную реализацию .
.
Поскольку jsdom
не реализует scrollIntoView
, оно будет неопределенным для элементов, предоставленных jsdom
.
Решение
рекомендуемый подход от этого разработчика Google заключается в добавлении следующей строки в ваш тестовый код:
Element.prototype.scrollIntoView = () => {};
Эта строка добавит реализацию noop scrollIntoView
к jsdom
-обеспечиваемому Element
.
Для вашего теста вы можете сделать еще один шаг и установить scrollIntoView
на spy
, чтобы убедиться, что он называется:
it('should render component correctly', () => {
const props = {
...defaultProps,
};
Element.prototype.scrollIntoView = jest.fn(); // set scrollIntoView to a spy
const wrapper = mount(<PageView {...props} />);
expect(wrapper).toMatchSnapshot();
expect(Element.prototype.scrollIntoView).toHaveBeenCalled(); // PASSES
});
Кроме того, Антонио прав, что вам не нужно использовать ReactDOM.findDOMNode()
, вы должны иметь возможность использовать this.topOfPageRef.current
напрямую:
componentDidMount() {
this.topOfPageRef.current.scrollIntoView();
}