I would like to test a small React web app where I use the global fetch method.
I tried to mock fetch in this way:
global.fetch = jest.spyOn(global, 'fetch').mockImplementation(endpoint =>
Promise.resolve({
json: () => Promise.resolve(mockResponse)
})
);
... but the mock seems to be ignored, while the built-in fetch seems to be used: Error: connect ECONNREFUSED 127.0.0.1:80 ... looks like a failed call to the built-in fetch.
I then tried to use jest.fn instead of jest.spyOn:
global.fetch = jest.fn(endpoint =>
Promise.resolve({
json: () => Promise.resolve(mockResponse)
})
);
... and was surprised to see a different error. Now the mock seems to be taken into consideration, but at the same time is not working correctly:
TypeError: Cannot read property 'then' of undefined
8 | this.updateTypes = this.props.updateTypes;
9 | this.updateTimeline = this.props.updateTimeline;
> 10 | fetch('/timeline/tags')
| ^
11 | .then(res => res.json())
12 | .then(tags => tags.map(tag => <option value={tag} key={tag} />))
13 | .then(options => options.sort((a, b) => a.key.localeCompare(b.key)))
I find the documentation of Jest and React Testing Library a bit confusing, honestly. What might be the problem with what I am doing?
Edit
The React component I am trying to test is called "App", was generated with Create React App, and was changed to include a call to fetch. I can gladly provide the code for this component, but I believe that the problem lies in the tests.
At the beginning of my App.test.js file, I import React from 'react';, then import { render, fireEvent, waitFor, screen } from '@testing-library/react';, and finally import App from './App';. I subsequently attempt to mock fetch in one of the ways I described, and then declare the following test:
test('renders a list of items, upon request', async () => {
const app = render(<App />);
fireEvent.click(screen.getByText('Update'));
await waitFor(() => screen.getByRole('list'));
expect(screen.getByRole('list')).toBeInTheDocument();
expect(screen.getByRole('list')).toHaveClass('Timeline');
});
Finally, I end my test file with global.fetch.mockRestore();.