最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - expect(jest.fn()).toHaveBeenCalled() error - Stack Overflow

programmeradmin2浏览0评论

I'm using Enzyme/Jest to write a test for a function on my container hat is triggered through an onChange of a checkbox ponent. 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!

I'm using Enzyme/Jest to write a test for a function on my container hat is triggered through an onChange of a checkbox ponent. 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!

Share Improve this question edited Jul 21, 2017 at 6:43 Andreas Köberle 111k58 gold badges280 silver badges307 bronze badges asked Jul 19, 2017 at 6:53 cssun25cssun25 3811 gold badge5 silver badges14 bronze badges 2
  • Why not just test that the state has changed? – Andreas Köberle Commented Jul 19, 2017 at 11:52
  • It won't work for me either, because the onChange function hasn't even been called. It seems like there's an issue with the "simulate change" portion, I don't get why it's not simulating the change (thereby not causing the onChange function to run, thereby not changing the state). – cssun25 Commented Jul 20, 2017 at 1:14
Add a ment  | 

1 Answer 1

Reset to default 3

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 ponent'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 ponent that have the click handler attached:

wrapper.find('Checkbox')
发布评论

评论列表(0)

  1. 暂无评论