2

I am testing a component that uses a useEffect hook that fetches data from an API, updates state and then builds out the component. I've mocked the API response successfully for several tests using this Stack Overflow answer as an example. I am now trying to write a test where I mock a returned error from the API. I'm getting an error stating TypeError: Cannot read property 'then' of undefined for fetch. I'm trying to use the same example but with no luck.

My successful fetch mock with test data looks like:

global.fetch = jest.fn().mockImplementationOnce(() =>
  Promise.resolve({
    json: () => Promise.resolve(successMockData),
  })
)

My attempted mock error response currently looks like:

global.fetch = jest.fn().mockImplementationOnce(() => {
  Promise.resolve({
    status: 400,
    json: () => Promise.resolve({ success: false, error: 'Something bad happened' }),
  })
})

The error that I get when running the test is: enter image description here

If I reject the promise, I still get the same error but get the thrown exception with it too:

global.fetch = jest.fn().mockImplementationOnce(() => {
  Promise.reject({
    status: 400,
    json: () => Promise.resolve({ success: false, error: 'Something bad happened' }),
  })
})

enter image description here

The API uses a NextApiResponse and looks like this:

try {
  // Query data from database
  const data = methodThatGetsDataFromDatabase()

  return res.status(200).json({ success: true, data: data })
} catch (error) {
  return res.status(400).json({ success: false, error: error.message })
}

I've been working at this for a long time and have about worn Google out looking for answers. I just can't figure out why fetch is undefined rather than returning the promise. Any help is greatly appreciated!

BSK
  • 733
  • 2
  • 7
  • 13

1 Answers1

4

The difference I found is that, your successful fetch mock actually returns the Promise.

But the failing fetch mock is not returning -- notice the subtle addition of curly braces around that Promise. Can you check this without that curly brackets?

global.fetch = jest.fn().mockImplementationOnce(() => 
  Promise.resolve({
    status: 400,
    json: () => Promise.resolve({ success: false, error: 'Something bad happened' }),
  })
)
Bms bharadwaj
  • 483
  • 5
  • 18
  • 3
    I was definitely looking at this code for to long because that was the issue. So simple... Always helps to get another set of eyes on it! Thanks so much! – BSK Jan 16 '22 at 00:27
  • Oh man I'd been struggling with the same issue and looked far and wide for an answer... only to realize it was this. Lifesaver. – sanya29 Nov 28 '22 at 00:32