8
votes

This one has me totally stumped despite trying everything.

I am testing a React component with Jest/Enzyme. This test simulates modifying a element which then calls an onChange method.

When I run test I get this from Jest:

Cannot spy the onChange property because it is not a function; undefined given instead

Why??

Here are the key parts of the component:

import React, {Component} from 'react';
import EntitiesPulldown from './entities-pulldown'

class NewTransactionForm extends Component  {

constructor(props) {
   super(props);

   this.state = {
       amount: "0.00",
       investors_4_picklist: [],
       selectedTType:0      
   };

   this.onChange = this.onChange.bind(this);
} 

onChange(event) {
      const value = event.target.value;
      const name = event.target.name;

      this.setState({
        [name]: value
      });
      console.log("just set "+name+"  to  "+value)

}

render() {
return (  
      <div>
           <EntitiesPulldown                                                                           
               itemList = {this.state.investors_4_picklist}                                                                                                                                                      
               handleChangeCB = {this.onChange}
             />
      </div>
  )
 }
}
export default NewTransactionForm;

Pretty straightforward. And here is the test:

test('NTF calls onChange after select', () => {
  const wrapperInstance = mount(<NewTransactionForm />).instance();

  const spy = jest.spyOn(wrapperInstance, 'onChange')  //fails

  wrapperInstance.update().find('select').simulate('change',{target: { name: 'selectedTType', value : 3}});

  expect(spy).toHaveBeenCalled();
});

And I also tried this option, same results:

  const spy = jest.spyOn(NewTransactionForm.prototype, 'onChange')

What am I doing wrong? Any help really appreciated.

1
As far as I can tell, that looks correct. I would check assumptions to make sure wrapperInstance is the object you expect it to be, and that you aren't doing something like accidentally importing the wrong component...Garrett Motzner
If you can include the header/imports for the test file, that might help.Garrett Motzner
What about spying on the prototype? jest.spyOn(wrapperInstance.prototype, 'onChange')evolutionxbox

1 Answers

3
votes

Thanks Garret. I have a new view into the problem, but not the answer. The component that was deployed was a wrapped HOC in order to use Material-UI Styles. Because it was an HOC, it was losing access to all the methods of the wrapped component.

The actual export was:

NewTransactionForm.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(NewTransactionForm);

When I took out the styling and exported with:

export default NewTransactionForm;

I was able to access the onChange function. I am now looking for ways to make the methods of the wrapped component accessible to outside calls, but that is another question.