score:8

Accepted answer

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


shallow

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.


mount

"The default environment in Jest is a browser-like environment through jsdom".

"jsdom is a pure-JavaScript implementation of many web standards...[that] emulate[s] enough of a subset of a web browser to be useful for testing".

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
});

Also, Antonio is correct that you shouldn't need to use ReactDOM.findDOMNode(), you should be able to use this.topOfPageRef.current directly:

componentDidMount() {
  this.topOfPageRef.current.scrollIntoView();
}

score:0

You can set in window

  it('should call paginator component', () => {
      window.HTMLElement.prototype.scrollIntoView = jest.fn();
      // arrange
      // act
      // assertion
  })
  

score:1

The error you get is because ReactDOM.findDOMNode is giving you back null.

As the React doc says:

When a component renders to null or false, findDOMNode returns null

also

In most cases, you can attach a ref to the DOM node and avoid using findDOMNode at all.

You should not use React.findDOMNode

componentDidMount() {
   ReactDOM.findDOMNode(this.topOfPageRef.current).scrollIntoView();
}

but:

componentDidMount() {
   this.topOfPageRef.current.scrollIntoView();
}

Hope it will help.


Related Query

More Query from same tag