TypeError: Cannot read property 'setState' of undefined in jest

Hi There,

I am trying to write a unit test for my child class and simulating a click event.

        Parent Class 
        
        handleClick(e) {
        this.setState({ showButton: !this.state.showButton })
       }
      render()
      {  
         <Child
           handleClick={this.handleClick}
           showButton={this.state.showButton}
           userInfo={el => this.userInfo= el />
      }

    Child class
      { render(){
            <div className="XX">
                <div id="user-info" ref={this.props.userInfo} onClick=
                              {this.props.handleClick}>
                  
                      }
       }

 Unit Test
  describe('Child Test', () => {
  let child
  let handleClickSpy= jest.spyOn(Parent.prototype, 'handleClick');

function configProps() {
    let props = {
        handleClick : handleClickSpy
        showButton: false

    };
    return props;
  }


  beforeEach(() => {
    let props = configProps();
    child = mount(<Child {...props} />);
    
  })


  it('should show logout div when userinfo div is clicked', () => {
    let button = child.find('#user-info');
    button.simulate('click');

    expect(handleClickSpy).toHaveBeenCalled();
  })

})

Can someone point out what is causing the error?

It looks like the code you posted has been truncated somehow.

It would be helpful if you also posted the full error message. It shows which line triggered the error.

Here is the complete log… Somehow It is not able to recognize handleClick

   TypeError: Cannot read property 'setState' of undefined

  at toggleLogoutSection (public\src\containers\Parent.js:35:17)
  at Object.invokeGuardedCallback [as invokeGuardedCallbackWithCatch] (node_modules\react-
  dom\lib\ReactErrorUtils.js:26:5
   )  at executeDispatch (node_modules\react-dom\lib\EventPluginUtils.js:83:21)
  at Object.executeDispatchesInOrder (node_modules\react-dom\lib\EventPluginUtils.js:108:5)
  at executeDispatchesAndRelease (node_modules\react-dom\lib\EventPluginHub.js:43:22)
  at executeDispatchesAndReleaseSimulated (node_modules\react-dom\lib\EventPluginHub.js:51:10)
  at forEachAccumulated (node_modules\react-dom\lib\forEachAccumulated.js:26:8)
  at Object.processEventQueue (node_modules\react-dom\lib\EventPluginHub.js:255:7)
  at node_modules\react-dom\lib\ReactTestUtils.js:350:22
  at ReactDefaultBatchingStrategyTransaction.perform (node_modules\react-
  dom\lib\Transaction.js:140:20)
  at Object.batchedUpdates (node_modules\react-dom\lib\ReactDefaultBatchingStrategy.js:62:26)
  at Object.batchedUpdates (node_modules\react-dom\lib\ReactUpdates.js:97:27)
  at node_modules\react-dom\lib\ReactTestUtils.js:348:18
  at ReactWrapper.<anonymous> (node_modules\enzyme\build\ReactWrapper.js:776:11)
  at ReactWrapper.single (node_modules\enzyme\build\ReactWrapper.js:1421:25)
  at ReactWrapper.simulate (node_modules\enzyme\build\ReactWrapper.js:769:14)
  at Object.<anonymous> (public\src\__tests__\component.tests\userInfo.test.js:38:16)
  at handle (node_modules\worker-farm\lib\child\index.js:44:8)
  at process.<anonymous> (node_modules\worker-farm\lib\child\index.js:51:3)
  at emitTwo (events.js:106:13)
  at process.emit (events.js:191:7)
  at process.nextTick (internal\child_process.js:744:12)
  at _combinedTickCallback (internal\process\next_tick.js:67:7)
  at process._tickCallback (internal\process\next_tick.js:98:9)

The line number points to the below piece of code –
this.setState({ showButton: !this.state.showButton })

Try binding your showButton method before you pass it:

<Child
           handleClick={this.handleClick}
           showButton={this.state.showButton.bind(this)} // << do this
           userInfo={el => this.userInfo= el />

Its giving me the same error :frowning:

<Child
           handleClick={this.handleClick.bind(this)} // << this too
           showButton={this.state.showButton.bind(this)} // << do this
           userInfo={el => this.userInfo= el />

You should bind handleClick, too, now that I think about it.

I am already binding it in the parent constructor… do i still need to bind it again?