Javascript TypeError:无法读取属性';滚动到视图';空-反应。玩笑酶
使用react 16.3.1、jest 16.3.1和酶3.3.0 在我的React类组件中,我创建了一个React引用,用于确保在安装组件时浏览器位于页面顶部Javascript TypeError:无法读取属性';滚动到视图';空-反应。玩笑酶,javascript,reactjs,testing,jestjs,enzyme,Javascript,Reactjs,Testing,Jestjs,Enzyme,使用react 16.3.1、jest 16.3.1和酶3.3.0 在我的React类组件中,我创建了一个React引用,用于确保在安装组件时浏览器位于页面顶部 class PageView extends React.Component { constructor(props) { super(props); this.topOfPageRef = React.createRef(); } componentDidMount() { ReactDOM.f
class PageView extends React.Component {
constructor(props) {
super(props);
this.topOfPageRef = React.createRef();
}
componentDidMount() {
ReactDOM.findDOMNode(this.topOfPageRef.current).scrollIntoView();
}
render(){
const { x } = this.props;
return (
<React.Fragment>
<div className="main-wrapper" ref={this.topOfPageRef}>
Top
</div>
)}
</React.Fragment>
);
}
}
类页面视图扩展了React.Component{
建造师(道具){
超级(道具);
this.topOfPageRef=React.createRef();
}
componentDidMount(){
ReactDOM.findDOMNode(this.topOfPageRef.current).scrollIntoView();
}
render(){
const{x}=this.props;
返回(
顶部
)}
);
}
}
这一切都可以在浏览器中完美运行,但在我的酶测试中失败
我的测试很简单,它只是尝试渲染组件
it('should render component correctly', () => {
const props = {
...defaultProps,
};
const wrapper = mount(<PageView {...props} />);
expect(wrapper).toMatchSnapshot();
});
it('应该正确呈现组件',()=>{
常量道具={
…默认道具,
};
const wrapper=mount();
expect(wrapper.toMatchSnapshot();
});
TypeError:无法读取null的属性“scrollIntoView”
我尝试了shallow和mount两种方法,虽然找到的元素不是null,但它似乎是HtmlLevel的react实例,缺少scrollIntoView方法。您得到的错误是因为ReactDOM.findDOMNode返回null 正如React doc所说: 当组件呈现为null或false时,findDOMNode返回null 也 在大多数情况下,可以将ref附加到DOM节点,并完全避免使用findDOMNode 您不应该使用React.findDOMNode
componentDidMount() {
ReactDOM.findDOMNode(this.topOfPageRef.current).scrollIntoView();
}
但是:
希望能有所帮助。错误消息澄清 在上面的示例代码中使用类似的
mount
会出现以下错误:
TypeError:\u reactDom2.default.findDOMNode(…).scrollIntoView不是函数
使用shall
会产生上面列出的错误:
TypeError:无法读取null的属性“scrollIntoView”
浅的 问题
shallow
不进行DOM渲染,因此永远不会有可调用scrollIntoView()
的DOM节点
解决方案
任何执行DOM操作的代码都需要使用mount
提供的完整DOM呈现进行测试
攀登 问题
jsdom
实现了大部分浏览器环境,但它并没有实现所有功能。这个问题需要特别注意的是,它没有实现scrollIntoView
,因为jsdom
因为jsdom
没有实现scrollIntoView
,它将在jsdom
提供的元素上未定义
解决方案
方法是在测试代码中添加以下行:
Element.prototype.scrollIntoView=()=>{}代码>
该行将把scrollIntoView
的noop实现添加到jsdom
-提供的元素中
对于您的测试,您可以更进一步,将scrollIntoView
设置为spy
,以确保调用它:
it('应该正确呈现组件',()=>{
常量道具={
…默认道具,
};
Element.prototype.scrollIntoView=jest.fn();//将scrollIntoView设置为间谍
const wrapper=mount();
expect(wrapper.toMatchSnapshot();
expect(Element.prototype.scrollIntoView).toHaveBeenCalled();//传递
});
此外,Antonio认为您不需要使用ReactDOM.findDOMNode()
,您应该能够直接使用this.topOfPageRef.current
:
componentDidMount(){
this.topOfPageRef.current.scrollIntoView();
}
您可以在窗口中进行设置
it('should call paginator component', () => {
window.HTMLElement.prototype.scrollIntoView = jest.fn();
// arrange
// act
// assertion
})
我到处都能看到这个修复程序,但您是从中导入元素的吗?“我得到”元素未定义“我正在使用带有chai的酶。@JamesTrickeyElement
引用来自DOM的类。forJest
是由jsdom
提供的类似浏览器的环境,它提供了全局范围内的元素
类(就像浏览器一样)。感谢您的清理。我用的是酶,但不是开玩笑,所以这就是为什么全球没有酶。最后,将功能提取到“服务”中,并将其传递给组件,以便对其进行模拟。不理想,但停止了错误。干杯,伙计们!
it('should call paginator component', () => {
window.HTMLElement.prototype.scrollIntoView = jest.fn();
// arrange
// act
// assertion
})