调用 renderHook() 后 waitFor 超时

时间:2021-07-25 19:36:22

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

我正在尝试测试一个简单的自定义钩子:

export const getSearchResults = async (searchText: string) => {
  const { data } = await axios.get(`${BASE_URL}/search`, {
    params: {
      searchText,
      apiToken: API_KEY
    },
  });

  return data as SearchResponse;
};

export default function useFetchSearch(searchTerm: string) {
  return useQuery<SearchResponse>([ 'search', searchTerm ], () => getSearchResults(searchTerm));
}

首先我尝试用 jest 来模拟 API 调用,然后我用 nock 进行了尝试,正如 react-query 文档 (https://react-query.tanstack.com/guides/testing) 中所说的那样。

我的测试如下:

it('Displays card', async () => {
    const queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    });

    const wrapper = ({ children }: any) => (
      <QueryClientProvider client={queryClient}>
        {children}
      </QueryClientProvider>
    );

    const BASE_URL = process.env.REACT_APP_API_URL;

    const expectation = nock(`${BASE_URL}`)
      .get('/search')
      .reply(200, {
        answer: 42
      });


    const { result, waitFor } = renderHook(() => useFetchSearch('test'), { wrapper });

    await waitFor(() => result.current.isSuccess, { interval: 100 });


    expect(result.current.data.answer).toEqual(42);
  });

我得到的错误是:错误:1000 毫秒后在 waitFor 中超时。

我的 package.json 如下:

"dependencies": {
    "@testing-library/dom": "7.21.4",
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/react-hooks": "^7.0.1",
    "@testing-library/user-event": "^12.1.10",
    "@types/jest": "^26.0.15",
    "@types/node": "^12.0.0",
    "@types/react": "16.9.0",
    "@types/react-dom": "16.9.0",
    "@types/react-router": "^5.1.12",
    "@types/react-router-dom": "^5.1.7",
    "axios": "^0.21.1",
    "nock": "^13.1.1",
    "react": "16.9.0",
    "react-dom": "16.9.0",
    "react-query": "^3.5.0",
    "react-router": "^5.2.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.1",
    "react-test-renderer": "16.9.0",
    "typescript": "^3.8.3",
  },

react-test-renderer、react 和 react-dom 的版本匹配。

任何输入都非常受欢迎!

1 个答案:

答案 0 :(得分:0)

从您的依赖项列表中,我会说您使用的是 axios,这与 react-query 文档中的示例使用的 不同。

来自nock documentation

<块引用>

Nock 通过覆盖 Node 的 http.request 函数来工作。此外,它也覆盖了 http.ClientRequest 以覆盖直接使用它的模块。

通过使用 axios,您可能不会直接使用 http.request

在关于 nock 和 axios 的文档中还有一个 common issues section

<块引用>

要将 Nock 与 Axios 一起使用,您可能需要配置 Axios 以使用 Node 适配器,如下例所示:

import axios from 'axios'
import nock from 'nock'
import test from 'ava' // You can use any test framework.

// If you are using jsdom, axios will default to using the XHR adapter which
// can't be intercepted by nock. So, configure axios to use the node adapter.
//
// References:
// https://github.com/nock/nock/issues/699#issuecomment-272708264
// https://github.com/axios/axios/issues/305
axios.defaults.adapter = require('axios/lib/adapters/http')

作为替代方案,我可以推荐使用 mock-service-worker 来拦截 webworker 层上的网络请求。优点是您不仅可以将这些模拟用于测试,还可以用于 storybook 之类的事情,甚至可以在开发过程中使用。