I am getting an Object.dispatchError when I run my unit test for my custom useFetch hook.
The hook:
import { useState, useEffect } from 'react';
const useFetch = (url) => {
const [data, setData] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
const apiCall = async () => {
try {
const res = await fetch(url);
if (!res.ok) throw new Error(`Error - ${res.status}`);
const json = await res.json();
setData(json);
setError(null);
} catch (err) {
setError(`useFetch Error!`);
} finally {
setLoading(false);
}
};
apiCall();
}, [url]);
return { data, loading, error };
};
export default useFetch;
My unit test:
import { renderHook, waitFor } from "@testing-library/react";
import useFetch from './useFetch';
it('Should handle no URL provided', async () => {
const { result } = renderHook(() => useFetch());
await waitFor(() => {
expect(result.current.error).toBe("useFetch Error!");
});
});
The error:
console.error
Error: AggregateError
at Object.dispatchError (jsdom\living\xhr\xhr-utils.js:63:19)
at Request.<anonymous> (jsdom\lib\jsdom\living\xhr\XMLHttpRequest-impl.js:655:18)
at Request.emit (node:events:531:35)
at ClientRequest.<anonymous> (jsdom\lib\jsdom\living\helpers\http-request.js:121:14)
at ClientRequest.emit (node:events:519:28)
at Socket.socketErrorListener (node:_http_client:492:9)
at Socket.emit (node:events:519:28)
at emitErrorNT (node:internal/streams/destroy:169:8)
at emitErrorCloseNT (node:internal/streams/destroy:128:3)
at processTicksAndRejections (node:internal/process/task_queues:82:21) undefined
Maybe it is my waitFor() in the unit test that is not written correctly?
How should I unit test my custom hook?
Cheers!
StackBlitz: useFetch Custom Hook
(Although, how you can run unit tests in stackblitz is beyond me...)
You've not provided a
URLto youruseFetchhook, so it's trying to make a request to an undefined URL. The error you're getting is related to the request itself, not the error handling within your hook.One way would be to mock the
fetchfunction to avoid making actual requests and simulate different scenarios for your hook. Something like:Sidenote: You can also leverage the msw package to write more accurate unit tests for APIs without resorting to manual mocking. MSW uses service workers behind the scenes to intercept API requests and inject test data before making the actual calls.