我有一个自定义的React钩子,如下所示:
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,
};
我想测试一下,当getPolicyByReference
不抛出时,isValidPolicyReference
会返回true,而当抛出时会返回false。
我对真实情况的测试如下:
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();
});
哪个通过了,但错误案例的测试没有通过:
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();
});
它在两个方面失败:
- isValidPolicyReference从不返回false
- 还有一个
console.error
记录在此线路setIsValid(false);
,其中Warning: Can't perform a React state update on an unmounted component.
我不知道如何让getPolicyByReference
在Jest中抛出,这样钩子就会返回false值。
我做错了什么?我应该用async
await
包装我的测试用例吗?我应该嘲笑axios.get
而不是getPolicyByReference
吗?
此行还记录了一个console.error setIsValid(false);其中警告:无法对未安装的组件执行React状态更新。
我认为问题是,当钩子只能从whithin组件调用时,您正试图用jest单独测试钩子。
react测试库有非常好的助手来简化测试挂钩,本文在这方面提供了大量信息。