使用 jest 和 renderhook 测试具有多个异步请求的自定义钩子

时间:2021-05-10 12:09:08

标签: reactjs jestjs react-hooks react-query

我一直在开发一个应用程序,该应用程序使用 react-query 来处理和缓存对后端的响应。从该框架背后的创建者那里获得了很多灵感,使用自定义钩子来处理后端状态。一开始很容易,但后来钩子开始相互依赖。这导致 CI​​ 中出现一些奇怪的行为,因为服务器上的负载过重导致一些测试用例失败。 (注意后端是用 msw 模拟的)

包含多个自定义钩子的自定义钩子:

const useFooMutation = () => {
    const cache = useQueryClient();
    const { types } = useTypes(); // async call to backend
    const { user } = useAuth(); // async call to backend

    return useMutation(['key'], mutationFunction, {
        onSuccess: async (data, variables) => {
            // Do cache handling by using values types and user
        },
    });
};

测试用例:

test('useFooMutation should foo', async () => {
    const { wrapper } = setupCache();
    const { result, waitFor, waitForNextUpdate } = renderHook(() => useFooMutation(), { wrapper });

    await waitForNextUpdate();

    act(() => {
        result.current.mutate({
            values
        });
    });

    await waitFor(() => result.current.isSuccess && !result.current.isLoading);
    expect(result.current.isSuccess).toEqual(true);
    expect(result.current.data).toEqual(fooMockData);
});

当我调试代码时,我发现有时尚未获取钩子 useTypes 和 useAuth 中的值。当我进行缓存操作时,会使用来自其他自定义钩子的值。所以这会导致某些机器出现一些奇怪的行为。例如,在本地运行这在大多数情况下都可以正常运行,但是在负载很重的 CI 服务器上,它经常导致崩溃。 到目前为止,我尝试过的是在测试用例中的突变函数之前添加一个超时似乎有效的超时,这不是一个很好的解决方案。并且通过使用 waitForNextUpdate 测试用例在大多数情况下都可以正常工作,但在加载 CI 时则不行。 所以我需要一个很好的方法来找出 useFooMutation 何时从它所依赖的钩子中收集了所有值,然后才能调用 mutate()?

0 个答案:

没有答案