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
1 Answer
Reset to default 3The 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')