Noxy444
Noxy444

Reputation: 1

Testing click event in enzyme on react functional component not passing

I'm trying to write a test for when my button is clicked, that the handleClick function will be called but I keep receiving false in the assertion from my test. Here's the React component:

function Profile() {

    const [name, setName] = useState({
        firstName: '',
        lastName: ''
    });
    const [names, setNames] = useState([]);

    const handleClick = (e) => {
        e.preventDefault();
        names.push(name);
    }

    return ( 
       <form >
        <input 
          type = "text"
          value = {name.firstName}
          onChange = {
            e => setName({
                ...name,
                firstName: e.target.value
            })
        }/> 
        <input 
          type = "text"
          value = {name.lastName}
          onChange = {
            e => setName({
                ...name,
                lastName: e.target.value
            })
        }/> 
        <button onClick = {handleClick} > Add Name < /button> </form>
    )
}
export default Profile

And here's the test:

it('test 1 - call handleClick spy', () => {
  const handleClick = sinon.spy();
  let wrapper = shallow(<Profile handleClick={handleClick}/>);  
  wrapper.find('button').simulate('click',{preventDefault:()=>{}});
  expect(handleClick.calledOnce).toBe(true); 
  }); 

Upvotes: 0

Views: 2590

Answers (1)

Lin Du
Lin Du

Reputation: 102287

The click event does not trigger the mocked handleClick method you pass in, but rather the handleClick method defined inside the component. This is why the mocked handleClick method is not called.

To determine if the handleClick method inside the component is being called, you can use indirect methods such as preventDefault to determine if the preventDefault function is being called.

E.g.

index.jsx:

import React, { useState } from 'react';

function Profile() {
  const [name, setName] = useState({
    firstName: '',
    lastName: '',
  });
  const [names, setNames] = useState([]);

  const handleClick = (e) => {
    e.preventDefault();
    names.push(name);
  };

  return (
    <form>
      <input
        type="text"
        value={name.firstName}
        onChange={(e) =>
          setName({
            ...name,
            firstName: e.target.value,
          })
        }
      />
      <input
        type="text"
        value={name.lastName}
        onChange={(e) =>
          setName({
            ...name,
            lastName: e.target.value,
          })
        }
      />
      <button onClick={handleClick}> Add Name </button>{' '}
    </form>
  );
}
export default Profile;

index.test.jsx:

import React from 'react';
import Profile from '.';
import { shallow } from 'enzyme';

describe('62202833', () => {
  it('should pass', () => {
    const wrapper = shallow(<Profile></Profile>);
    const mEvent = { preventDefault: jest.fn() };
    wrapper.find('button').simulate('click', mEvent);
    expect(mEvent.preventDefault).toBeCalledTimes(1);
  });
});

unit test result:

 PASS  stackoverflow/62202833/index.test.jsx (13.273s)
  62202833
    ✓ should pass (12ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |   85.71 |      100 |      50 |      80 |                   
 index.jsx |   85.71 |      100 |      50 |      80 | 21-31             
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        15.05s

Upvotes: 3

Related Questions