Joe*_*oel 2 javascript testing reactjs jestjs enzyme
使用反应 16.3.1,开玩笑 16.3.1,酶 3.3.0。
在我的 React Class 组件中,我创建了一个 react ref,我用它来确保安装组件时浏览器位于页面顶部。
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
这一切都在浏览器中完美运行,但在我的酶测试中失败了。
我的测试很简单,它只是尝试渲染组件。
it('should render component correctly', () => {
const props = {
...defaultProps,
};
const wrapper = mount(<PageView {...props} />);
expect(wrapper).toMatchSnapshot();
});
Run Code Online (Sandbox Code Playgroud)
TypeError: Cannot read property 'scrollIntoView' of null
我已经尝试了浅层和挂载方法,虽然找到的元素不为空,但它似乎是 HTMLDivElement 的反应实例,它缺少 scrollIntoView 方法。
Error message clarification
Using mount like in the sample code above gives this error:
TypeError: _reactDom2.default.findDOMNode(...).scrollIntoView is not a function
Using shallow gives the error listed above:
TypeError: Cannot read property 'scrollIntoView' of null
Issue
shallow does not do DOM rendering so there will never be a DOM node on which to call scrollIntoView().
Solution
Any code that does DOM manipulation needs to be tested using the full DOM rendering provided by mount.
"The default environment in Jest is a browser-like environment through jsdom".
Issue
jsdom implements much of the browser environment but it does not implement everything. Of particular note for this question is that it does not implement scrollIntoView since jsdom does not do layout and would therefore not be able to provide an accurate implementation.
Because jsdom does not implement scrollIntoView it will be undefined on elements provided by jsdom.
Solution
The recommended approach from this Google dev is to add the following line to your test code:
Element.prototype.scrollIntoView = () => {};
That line will add a noop implementation of scrollIntoView to the jsdom-provided Element.
For your test you could take it a step further and set scrollIntoView to a spy to make sure it is called:
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
});
Run Code Online (Sandbox Code Playgroud)
另外,Antonio 是正确的,您不需要使用ReactDOM.findDOMNode(),您应该可以this.topOfPageRef.current直接使用:
componentDidMount() {
this.topOfPageRef.current.scrollIntoView();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19560 次 |
| 最近记录: |