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