Dániel Kocsis
Dániel Kocsis

Reputation: 31

waitFor times out after calling renderHook()

I am trying to test a simple custom hook:

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));
}

First i tried to mock the API call with jest, then I tried it with nock as it says in the react-query docs (https://react-query.tanstack.com/guides/testing).

My test looks the following:

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);
  });

the error I am getting is: Error: Timed out in waitFor after 1000ms.

My package.json is the following:

"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",
  },

Versions of react-test-renderer, react and react-dom are matching.

Any input is highly appriciated!

Upvotes: 2

Views: 5984

Answers (2)

D&#225;niel Kocsis
D&#225;niel Kocsis

Reputation: 31

Thanks for all the inputs. I found what the issue was:

I accidentally mocked my custom hook with jest before running my test. After removing jest.mock('getSearchResults'), it worked as expected.

Upvotes: 1

TkDodo
TkDodo

Reputation: 28743

From your dependencies list, I would say that you are using axios, which is not what the examples in the react-query docs are using.

From the nock documentation:

Nock works by overriding Node's http.request function. Also, it overrides http.ClientRequest too to cover for modules that use it directly.

By using axios, you are likely not using http.request directly.

There is also a common issues section in the docs about nock and axios:

To use Nock with Axios, you may need to configure Axios to use the Node adapter as in the example below:

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')

As an alternative, I can recommend using mock-service-worker to intercept network requests on a webworker layer. Advantages are that you can not only use these mocks for tests, but also for things like storybook or even during development.

Upvotes: 1

Related Questions