Max Millington
Max Millington

Reputation: 4473

Jest not recognizing spy is called

I'm having a little trouble confirming my function is called using Jest. I've got two mocked functions. One is just mocked to return a promise, the other is a simple spy that should be called in the then() block of the first.

Below, in the test, you will see two expectations. The first expectation passes. The second does not. i.e. expect(sendSpy).toHaveBeenCalled() passes but expect(sendCallbackSpy).toHaveBeenCalled() does not.

However, when I put the console.log statements in the file (as below), both execute (i.e. the 'before' and 'after'), and if I console log the window.props.onSend it confirms that the mocked function is present. So it looks like the function should be called.

Another thing of note is that my implementation requires me to pass in the callback in a props object from my window. Further, to mock things on the window in Jest, you just mock global as I'm doing below. I don't think that is relevant to the issue but worth pointing out nonetheless.

Could it be that the expectation is run before the actual function is called in the then() block?

export class MyButton extends Component {
  handleClick = () => {
    this.props.send(this.props.url).then(res => {
      console.log('before', window.props.onSend)
      window.props.onSend(res.data)
      console.log('after')
    })
  }

  render() {
     return <button onClick={handleClick} />
  }
}



//test

  test('it calls the identity function when button is clicked', () => {
    const sendSpy = jest.fn(() => { return Promise.resolve({ data: 'hello' }) })
    const sendCallbackSpy = jest.fn()
    global.props = { onSend: sendCallbackSpy }

    wrapper = shallow(<MyButton send={sendSpy} } />)
    const button = wrapper.find('button')
    button.simulate('click')

    expect(sendSpy).toHaveBeenCalled()
    expect(sendCallbackSpy).toHaveBeenCalled()
  })

Upvotes: 2

Views: 5445

Answers (1)

Andreas K&#246;berle
Andreas K&#246;berle

Reputation: 111092

You need to wait for the promise before testing the second spy:

test('it calls the identity function when button is clicked', async() => {
    const request = Promise.resolve({ data: 'hello' })
    const sendSpy = jest.fn(() => request)
    const sendCallbackSpy = jest.fn()
    global.props = { onSend: sendCallbackSpy }

    wrapper = shallow(<MyButton send={sendSpy} } />)
    const button = wrapper.find('button')
    button.simulate('click')

    expect(sendSpy).toHaveBeenCalled()
    await request
    expect(sendCallbackSpy).toHaveBeenCalled()
})

Upvotes: 3

Related Questions