Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest/React mock scrollBy and .getBoundingClientRect function

I have a function handleClick which uses scrollBy on an element which gets its first argument using getBoundingClientRect. I am trying to test this using jest/enzyme.

class myClass extends Component  {
    ...
    ...
    handleClick () {
        document.getElementById('first-id').scrollBy(document.getElementById('second-id').getBoundingClientRect().width, 0);
    }

    render() {
        return (
            <button className="my-button" onClick={this.handleClick()}>scroll</button>
        );
    }
}

My test:

it('calls scrollBy with correct params', () => {
    const props = {};
    myClassWrapper = mount(<myClass {...props} />);
    const scrollBySpy = jest.fn();
    global.document.getElementById = jest.fn(() => ({ scrollBy: scrollBySpy }));

    myClassWrapper.find('my-button').simulate('click');
    // expect(scrollBySpy).toHaveBeenCalledWith()
});

I am trying to test that scrollBy is getting called with correct params, but I get the following error when running this test:

Error: Uncaught [TypeError: document.getElementById(...).getBoundingClientRect is not a function] 

Sorry if this has been answered before but I could not see anything which answers my scenario. Thank you in advance.

like image 830
Mohammed Avatar asked Mar 04 '23 02:03

Mohammed


1 Answers

scrollBy is called on the first result of getElementById, and getBoundingClientRect is called on the second result of getElementById so you'll need to include both functions on the object you are returning in the mock.

Here is a working example to get you started:

import * as React from 'react';
import { mount } from 'enzyme';

class MyClass extends React.Component {
  handleClick() {
    document.getElementById('first-id').scrollBy(document.getElementById('second-id').getBoundingClientRect().width, 0);
  }

  render() {
    return (
      <button className="my-button" onClick={this.handleClick}>scroll</button>
    );
  }
}

it('calls scrollBy with correct params', () => {
  const props = {};
  const myClassWrapper = mount(<MyClass {...props} />);
  const scrollBySpy = jest.fn();
  const getBoundingClientRectSpy = jest.fn(() => ({ width: 100 }));
  global.document.getElementById = jest.fn(() => ({
    scrollBy: scrollBySpy,
    getBoundingClientRect: getBoundingClientRectSpy  // <= add getBoundingClientRect
  }));

  myClassWrapper.find('.my-button').simulate('click');
  expect(scrollBySpy).toHaveBeenCalledWith(100, 0);  // Success!
});
like image 99
Brian Adams Avatar answered Apr 14 '23 04:04

Brian Adams