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

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

#1

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?


#2

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.


#3

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)

#4

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


#5

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 />

#6

Its giving me the same error :frowning:


#7
<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.


#8

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