I have a custom React hook as follows:
export function useValidPolicyReference({
token,
tenant,
policyReference,
}: UseValidPolicyReferenceProps): Record<string, boolean> {
const [isValid, setIsValid] = React.useState<boolean>(true);
React.useEffect(() => {
async function fetchOnMount(): Promise<void> {
try {
await getPolicyByReference({
policyReference: policyReference as string,
tenant,
token,
});
} catch (error) {
setIsValid(false);
}
}
if (tenant !== '' && policyReference !== null && token !== '') {
fetchOnMount();
}
}, [policyReference, tenant, token]);
return {
isValidPolicyReference: isValid,
};
I want to test that isValidPolicyReference will return true when getPolicyByReference does not throw and false when it does.
My test for the true case is as follows:
test('should be truthy if the policy reference is valid', () => {
(getPolicyByReference as jest.Mock).mockImplementationOnce(() =>
Promise.resolve(true)
);
const {
result: { current },
waitForNextUpdate,
} = render();
expect(current.isValidPolicyReference).toBeTruthy();
waitForNextUpdate();
expect(getPolicyByReference).toHaveBeenCalledWith({
token,
tenant,
policyReference,
});
expect(current.isValidPolicyReference).toBeTruthy();
});
Which passes but the test for the false case does not:
test('should be falsy if the policy reference is invalid', () => {
(getPolicyByReference as jest.Mock).mockImplementationOnce(() =>
Promise.reject(new Error('policy reference error'))
);
const {
result: { current },
waitForNextUpdate,
} = render();
expect(current.isValidPolicyReference).toBeTruthy();
waitForNextUpdate();
expect(current.isValidPolicyReference).toBeFalsy();
});
It fails on two counts:
console.error logged at this line setIsValid(false); where Warning: Can't perform a React state update on an unmounted component.I am not sure how to get getPolicyByReference to throw in Jest so that the hook will return the false value.
What am I not doing correctly? Should I be wrapping my test cases in async await? Should I mock axios.get instead of getPolicyByReference?
There is also a console.error logged at this line setIsValid(false); where Warning: Can't perform a React state update on an unmounted component.
I think the issue is you are trying to test the hook alone with jest, when hooks can only be called from whithin components.
The react testing library has really nice helpers to simplify testing hooks, this article is quite informative on the matter.