React-Query - 使用 react-testing-library 进行单元测试

时间:2021-01-14 11:08:18

标签: reactjs typescript react-testing-library react-query

我有一个 Dashboard 组件,其中包含一个子组件,例如Child 使用了 react-query。

我有一个 Dashboard 组件的现有单元测试开始失败,错误是:

TypeError: queryClient.defaultQueryObserverOptions is not a function

  38 |     const { locale } = React.useContext(LocaleStateContext);
  39 |     const options = getOptions(locale);
> 40 |     return useQuery(
     |            ^
  41 |         rqKey,
  42 |         async () => {
  43 |             const result = await window.fetch(url, options);

测试片段:

const queryClient = new QueryClient();
const { getByTestId, getByRole } = render(
    <IntlProvider locale="en" messages={messages}>
        <QueryClientProvider client={queryClient}>
            <Dashboard />
        </QueryClientProvider>
    </IntlProvider>,
);

我阅读了有关测试的文档:

https://react-query.tanstack.com/guides/testing#our-first-test

但我不想一定要使用 renderHook,因为我对结果不感兴趣。

编辑:

Child 组件正在使用一个函数:

export function usePosts({ rqKey, url, extraConfig }: CallApiProps) {
    const { locale } = React.useContext(LocaleStateContext);
    const options = getOptions(locale);
    return useQuery(
        rqKey,
        async () => {
            const result = await window.fetch(url, options);
            const data = await result.json();
            return data;
        },
        extraConfig,
    );
}

被称为:

const { data, error, isFetching, isError } = usePosts({
        rqKey,
        url,
        extraConfig,
    });

根据您的回答,我应该创建一个单独的函数:

async () => {
            const result = await window.fetch(url, options);
            const data = await result.json();
            return data;
        },

例如

export async function usePosts({ rqKey, url, extraConfig }: CallApiProps) {
    const { locale } = React.useContext(LocaleStateContext);
    const options = getOptions(locale);
    return useQuery(
        rqKey,
        await getFoos(url, options),
        extraConfig,
    );
}

然后在测试中模拟它。

如果我这样做,我将如何访问:error, isFetching, isError

因为 usePosts() 现在将返回一个 Promise<QueryObserverResult<unknown, unknown>>

编辑 2:

我尝试简化我的代码:

export async function useFetch({ queryKey }: any) {
    const [_key, { url, options }] = queryKey;
    const res = await window.fetch(url, options);
    return await res.json();
}

然后用作:

const { isLoading, error, data, isError } = useQuery(
    [rqKey, { url, options }],
    useFetch,
    extraConfig,
);

一切正常。

Dashboard 测试中,我执行以下操作:

import * as useFetch from ".";

jest.spyOn(useFetch, "useFetch").mockResolvedValue(["asdf", "asdf"]);

render(
        <IntlProvider locale="en" messages={messages}>
            <QueryClientProvider client={queryClient}>
                <Dashboard />
            </QueryClientProvider>
        </IntlProvider>,
    );

然后返回:

TypeError: queryClient.defaultQueryObserverOptions is not a function

      78 |     const { locale } = React.useContext(LocaleStateContext);
      79 |     const options = getOptions(locale);
    > 80 |     const { isLoading, error, data, isError } = useQuery(
         |                                                 ^
      81 |         [rqKey, { url, options }],
      82 |         useFetch,
      83 |         extraConfig,

0 个答案:

没有答案