I'm working on a react+ts app, where one can search for users using the gitHub API.
My search input looks like this :
<input
type="text"
placeholder="Search users by name"
className={styles.toolbar__searchInput}
onChange={handleChange}
/>
And the handleChange function is debounced to avoid making too many requests. I'm also checking that the response is OK :
const handleChange = debounce(async (event:React.ChangeEvent<HTMLInputElement>) => {
try {
const response = await fetch(`https://api.github.com/search/users?q=${event.target.value}`);
if (!response.ok && response.status === 403) {
throw new Error('API rate limit exceeded');
}
const users = await response.json();
props.setResults(users.items);
} catch (error) {
console.error(error);
}
});
When the fetch succeeds, users are saved in the app state with props.setResults()
.
Now I'm trying to test the fetch Response with jest, but I get an error like TypeError: Cannot read properties of undefined (reading 'ok')
My test looks like :
(global as any).fetch = jest.fn(async() =>
Promise.resolve({
"ok": true,
"status": 200,
json: () => Promise.resolve({
"items": [
{
"login": "roxxorDev1",
"id": 12345,
// ...
}
],
})
})
);
test.only('typing in the search input triggers a fetch', async () => {
jest.useFakeTimers();
render(<App />);
const searchInput:HTMLInputElement = screen.getByPlaceholderText('Search users by name');
searchInput.focus();
userEvent.keyboard('roxxorDev1');
searchInput.dispatchEvent(new Event('change'));
jest.runOnlyPendingTimers();
const user = screen.getByText('roxxorDev1');
expect(user).toBeInTheDocument();
});
How should I proceed ?