Enzyme: shallow rendered simulate('change') doesn't faithfully simulate change?

Created on 14 Apr 2017  路  8Comments  路  Source: enzymejs/enzyme

Fairly new to React and very new to Enzyme, I could be misunderstanding one or the other...any thoughts appreciated! (I found several similar discussions but they all seemed just to suggest workarounds)

I have a component that works in production but fails a new unit test I'm attempting to write. It appears to me that enzyme's simulate('change') causes the component to behave differently than an actual browser change event.

The component's job is to present radio buttons to the user, for them to select a number of days (in the past), and generate a start date and end date corresponding to the choice (e.g. user selects 7 days, start = now-7d, end=now)

Here is a snippet of the component showing the issue:

import React, {Component} from 'react';
import moment from 'moment';

export class RelativeDays extends Component {

  _handleChange = (event) => {
    console.log(event.target.value);
    this.props.updateFcn(
      moment().subtract(Number(event.target.value), 'days').startOf('minute'),
      moment().startOf('minute'));
  }

  render() {
    return (
      <div>
        <input id="aggregate_7"
                 name="seven" type="radio"
                 value="7"
                 onChange={this._handleChange}>
        </input>
      </div>
    );
  }
}

The test:

test('Past Week button', t => {

  const handleChange = sinon.spy()

  const wrapper = shallow(
    <RelativeDays startDate={moment()}
                  endDate={moment()}
                  updateDaysFcn={handleChange}/>
  );

  wrapper.find({id: 'aggregate_7'}).simulate('change')
...
});

The problem:

```

14: console.log(event.target.value);
15:

Error thrown in test

Error:

[TypeError: Cannot read property 'target' of undefined]

RelativeDays._this._handleChange (src/apps/UserAggregationApp/components/SevenDays.js:14:17)
```

...so, while event.target.value is '7' in the browser, event is undefined in the test.

Most helpful comment

For anyone having this issue, the docs explain that a mock event object can be passed as an optional second parameter to .simulate.

In the example above, we would want to update .simulate('change') to be .simulate('change', { target: { value: '7' } })

All 8 comments

The point of simulate for foo is to fire the onFoo handler - it's not to actually fully replicate browser interactions around events.

@ljharb ok - thanks for the reply!

For anyone having this issue, the docs explain that a mock event object can be passed as an optional second parameter to .simulate.

In the example above, we would want to update .simulate('change') to be .simulate('change', { target: { value: '7' } })

@thomkrillis I have a state value, which should change with simulation of change, I tried your method .simulate('change', { target: { value: '7' } }) but still, state value is not changed. Anything else which I can do

@shivanigambhir The solution I proposed above should specifically work for the original code in the issue because the element whose change is being simulated has an attribute onChange={this._handleChange} where the function _handleChange requires an input event and needs to access the value of event.target.value.

If you have a similar setup, the first things you should do is try something like the line console.log(event.target.value); in _handleChange to confirm that it is not undefined. If it is still undefined after including the second argument in simulate, then I would suspect there is something different about your setup. If it is not undefined, but the state is not being changed, I would expect a scoping issue with this. I would try the equivalent of changing onChange={this._handleChange} to onChange={this._handleChange.bind(this)}. If that does not help, then the problem is likely out of my depth.

@thomkrillis my setup is very much similar the above given scenario.event.target.value is not undefined also i tried using onChange={this._handleChange.bind(this)} but no luck. I saw similar issue https://github.com/airbnb/enzyme/issues/400 which is closely related to same.

As of now, trying to find alternatives.

@shivanigambhir try the solution from here: https://github.com/airbnb/enzyme/issues/1283

Thanks @thomkrillis !. That worked perfectly

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thurt picture thurt  路  3Comments

dschinkel picture dschinkel  路  3Comments

potapovDim picture potapovDim  路  3Comments

amcmillan01 picture amcmillan01  路  3Comments

aweary picture aweary  路  3Comments