I need to test catch
when fetching data request rejects but I don't understand why error is not catched and I recieved this error: UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with.catch(). (rejection id: 2)
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with.catch(). (rejection id: 2)
I have situation like this:
export const Container = ({fetchFirstAsset, fetchSecondAsset}) => {
const [status, setStatus] = useState(null);
async function fetchAssets() {
setStatus(IN_PROGRESS);
try {
await fetchFirstAsset();
await fetchSecondAsset()
setStatus(SUCCESS);
} catch {
setStatus(FAILURE);
}
}
useEffect(() => {
fetchAssets();
}, []);
....
};
And test like this:
import {mount} from 'enzyme';
import {act} from 'react-dom/test-utils';
const fetchFirstAsset = jest.fn();
const fetchSecondAsset = jest.fn();
it('should render without errors', async () => {
fetchFirstAsset.mockReturnValueOnce(Promise.resolve());
fetchSecondAsset.mockReturnValueOnce(Promise.reject());
let component;
await act(async () => {
component = mount(
<Container
fetchFirstAsset={fetchFirstAsset}
fetchSecondAsset={fetchSecondAsset}
/>
);
});
expect(fetchSomething).toHaveBeenCalled();
});
If I test case when fetchSomething
resolves with Promise.resolve()
evertyhing works fine and tests are correct but when I try to Promise.reject()
in order to test catch
case then this error is not catched and I have unhandled promise rejection
. (Why code looks like this: In other places in the app I handle changing of status with redux, so testing of catch is easy, but in one place I need to fetch 3 different assets for component and I decided to handle change of status with useState
because extracting 3 different statuses from redux and combining it will be ugly, with useState
is much cleaner i think)
Thanks in advance for help: :)
I had the same problem whereby the try/catch clause does not work when used within useEffect(). I did a few searches and it appears this is a potential bug, take a look at:
https://github.com/testing-library/react-hooks-testing-library/issues/305
That said, I was able to address the issue as follows:
FAILURE EXAMPLE:
useEffect(() => {
try {
invokeMyAsyncFunction();
setStatus(SUCCESS);
} catch (e) {
setStatus(FAILURE); // <== will not be invoked on exception!!
}
}
SUCCESS EXAMPLE:
useEffect(() => {
invokeMyAsyncFunction()
.then((response:any) => {
setStatus(SUCCESS);
})
.catch((e) => {
setStatus(FAILURE); // <== this **WILL** be invoked on exception
});
}
you need to write your catch block like this:
catch (e) {
// can do something with e in here
setStatus(FAILURE);
}
That's a good one, You need to declare your function inside the useEffect and implement the try/catch block inside of it, and outside of the function you only call it
(also, don't forget to cleanup your useeffect)
useEffect(() => {
const fetchAssets = async () => {
setStatus(IN_PROGRESS);
try {
await fetchFirstAsset();
await fetchSecondAsset()
setStatus(SUCCESS);
} catch {
setStatus(FAILURE);
}
}
fetchAssets();
}, []}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.