首页 > 解决方案 > 使用 jest 和 renderhook 测试具有多个异步请求的自定义钩子

问题描述

我一直在开发一个应用程序,它使用 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()?

标签: reactjsjestjsreact-hooksreact-query

解决方案


推荐阅读