How to mock e.preventDefault in react component's child

34,043

Solution 1

Try this

link.simulate('click', {
  preventDefault: () => {
  }
 });

Solution 2

 test('simulates click events', () => {
    const e = { stopPropagation: jest.fn() };
    const component = shallow(<ListItem{...props} />);
    const li = component.find('li').at(0).childAt(0)
    li.props().onClick(e)

    expect();
  });

Solution 3

Just to note that this is an issue only when using shallow enzyme renderer. In case of full DOM renderer mount, the event object contains the preventDefault method, therefore you don't have to mock it.

Solution 4

For those using Jest and @testing-library or react-testing-librarys fireEvent, you need to provide an initialised event object, otherwise the event can't be dispatched via your element.

One can then assert on e.preventDefault being called by assigning a property to that initialised event:

test('prevents default on click', () => {
  const {getByText} = render(<MyComponent />);
  const button = getByText(/click me/);

  // initialise an event, and assign your own preventDefault
  const clickEvent = new MouseEvent('click');
  Object.assign(clickEvent, {preventDefault: jest.fn()});

  fireEvent(button, clickEvent);

  expect(clickEvent.preventDefault).toHaveBeenCalledTimes(1);
});

Similarly for stopPropagation.

Anton Karpenko's answer for Jest was useful.

Solution 5

You can define an object with regarding function you will mock via some testing tool, for example look at Jest and Enzyme

describe('Form component', () => {
  test('deos not reload page after submition', () => {
    const wrapper = shallow(<TodosForm />)
    // an object with some function
    const event = { preventDefault: () => {} }
    // mocks for this function
    jest.spyOn(event, 'preventDefault')
    wrapper.find('form').simulate('submit', event)
    // how would you know that function is called
    expect(event.preventDefault).toBeCalled()
  })
})
Share:
34,043
Sergei Panfilov
Author by

Sergei Panfilov

“If you ask me what belt I am today… I’ll tell you that I’m a white belt that never gave up.” — Jean Jacques Machado

Updated on January 22, 2022

Comments

  • Sergei Panfilov
    Sergei Panfilov over 2 years

    Hy, I don't know how to mock an inline function in React component's child

    My stack: sinon, chai, enzyme;

    Component usage:

    <ListItem onClick={() => someFn()} />
    

    Component's render:

    render() {
        return (
          <li>
            <a href="#" onClick={e => {
                e.preventDefault();
                this.props.onClick();
              }}
            > whatever </a>
          </li>
        );
      }
    

    Here we have onClick function that calls e.preventDefault(). How to tell to <a href>(link) to not to call e.preventDefault()? How can I mock an onClick?

    Below is what I have tried in tests:

    Shallow copy setup

    function setup() {
      const someFn = sinon.stub();
    
      const component = shallow(
        <ListItem
          onClick={() => {
            someFn();
          }}
        />
      );
    
      return {
        component: component,
        actions: someFn,
        link: component.find('a'),
        listItem: component.find('li'),
      }
    }
    

    And the test

      it('simulates click events', () => {
        const { link, actions } = setup();
        link.simulate('click'); //Click on <a href>
        expect(actions).to.have.property('callCount', 1); //will be fine if we remove e.preventDefault()
      });
    

    Test's output error:

    TypeError: Cannot read property 'preventDefault' of undefined