BSK
BSK

Reputation: 743

Fetch is Undefined in Component when Mocking API Error Response with Jest

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!

Upvotes: 2

Views: 6273

Answers (1)

Bms bharadwaj
Bms bharadwaj

Reputation: 533

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' }),
  })
)

Upvotes: 5

Related Questions