expect(jest.fn()).toHaveBeenCalled() error

23,296

The problem is your selector wrapper.find('.checkbox').first(). This will trigger the event on <div className="checkbox">. But this element does not have the event listener, and .simulate does not behave like real events so it does not propagate. From the docs:

Currently, event simulation for the shallow renderer does not propagate as one would normally expect in a real environment. As a result, one must call .simulate() on the actual node that has the event handler set. Even though the name would imply this simulates an actual event, .simulate() will in fact target the component's prop based on the event you give it. For example, .simulate('click') will actually get the onClick prop and call it.

To fix this you have to select the component that have the click handler attached:

wrapper.find('Checkbox')
Share:
23,296
cssun25
Author by

cssun25

Updated on July 21, 2020

Comments

  • cssun25
    cssun25 almost 4 years

    I'm using Enzyme/Jest to write a test for a function on my container hat is triggered through an onChange of a checkbox component. I'm attempting to simulate a 'change', however, somehow the 'change' is not triggering the onChange function to be called. Not sure what is going on here... I've tried to change the simulate to a 'click', removed the target object and it still did not work.

    Container

    export class Data extends React.PureComponent {
      constructor(props) {
        super(props);
    
        this.state = {
          data_list_api: [],
          selected_data: this.props.dataForm,
        };
    
      }
    
    handleCheck = (event) => {
        const newSelectedData = Object.assign({}, this.state.selected_data);
        if (newSelectedData[event.target.name]) {
          delete newSelectedData[event.target.name];
        } else {
          newSelectedData[event.target.name] = [true, event.target.id];
        }
        this.setState({ selected_data: newSelectedData });
      }
    
    render() {
        const dataOptions = this.state.data_list_api.map((val, index) => (
          <div className="form-group no-margin" key={index}>
            <div className="col-md-12">
              <div className="checkbox">
                <Checkbox
                  name={val.data_name}
                  id={val.data_id}
                  onChange={this.handleCheck}
                  checked={this.state.selected_datas[val.data_name] ? true : false}
                  disabled={!this.state.selected_datas[val.data_name] && this.getObjectLength(this.state.selected_datas) > 3}
                />
              </div>
            </div>
          </div>
        ));
    
        return (
          <div>
           {dataOptions}
          </div>
        )
      }
    }
    

    Test

    import React from 'react';
    import { shallow, mount, render } from 'enzyme';
    import { fromJS } from 'immutable';
    import { Data } from '../index';
    
    function setup() {
      const props = {
        submitDataForm: jest.fn(),
      }
      const wrapper = shallow(<Data {...props} />);
      return { props, wrapper };
    }
    
    it('expects handleCheck to work', () => {
    const { wrapper, props } = setup();
    
    wrapper.setState({ data_list_api: [
      { data_name: 'data1 name',
        data_id: 123 },
      { data_name: 'data2 name',
        data_id: 234 },
      { data_name: 'data2  name',
        data_id: 345 }],
    });
    
    wrapper.instance().handleCheck = jest.fn();
    
    wrapper.update();
    
    wrapper.find('.checkbox').first().simulate('change', { target: { checked: true } });
    
    expect(wrapper.instance().handleCheck).toHaveBeenCalled();
    expect(wrapper).toMatchSnapshot();
    
    
    });
    

    Error

     expect(jest.fn()).toHaveBeenCalled()
    
    Expected mock function to have been called.
    
      at Object.<anonymous> (app/containers/Schools/tests/index.test.js:95:44)
          at Promise (<anonymous>)
      at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:169:7)
    

    Any help would be much appreciated!