首页 > 解决方案 > 测试基于超时刷新令牌的反应钩子

问题描述

export const useRefreshingToken = ({ ixId, learnerId, registrationId }: UseRefreshingTokenProps) => {

     const [timeoutId, setTimeoutId] = useState<number | null>(null);

    const { error, loading, reload, result } = useFetchData(gqlSdk.getToken, {
        itemId,
        userId,
        registrationId,
    });

    // Effect to refresh token ${tokenRefreshOffsetSeconds} before it expires
    useEffect(() => {
        if (!result?.token) {
            return;
        }

        // if there is already a scheduled reload dont need to set it again
        if (timeoutId || loading) {
            return;
        }

        const id = window.setTimeout(() => {
            reload();
            setTimeoutId(null);
            // Multiply by 1000 to go from seconds to milliseconds
        }, getRefreshTimeInMilliseconds(result.token.lifetimeSeconds));
        setTimeoutId(id);
    }, [reload, result, timeoutId, loading]);

    return {
        authToken: result?.token.tokenValue,
        loading: loading,
        error: error,
    };

我编写了这个钩子,它在我的 authtoken 即将到期时更新它的值。我想知道如何在这里测试刷新逻辑。

我可以使用 react-hook-testing 库测试这个钩子的第一次渲染。

    it('Fetches a token from the gql api', async () => {
        mockedSdk.getToken.mockResolvedValueOnce({
            token: { lifetimeSeconds: 10, tokenValue: 'some-token' },
        });

        const { result, waitForNextUpdate } = renderHook(() =>
            useRefreshingToken({ id: 'ix1', userId: 'learner1', registrationId: 'registration1' }),
        );

        await waitForNextUpdate();

        expect(result.current.authToken).toEqual('some-token');
    });

我尝试添加一段代码 await sleep(10) 休眠 10 秒,然后检查钩子的结果值。但是,这似乎不起作用。或者更确切地说,状态更新发生了,但我可能会在 act() 之外执行状态更新时出错。

标签: react-hooks

解决方案


我想到了。

我可以

jest.useFakeTimers()
await act(async () => {
            jest.runAllTimers();
            await waitForNextUpdate();
        })

伪造一个计时器并执行它。


推荐阅读