Apollo MockedProvider cannot return data using useLazyQuery with onCompleted

Viewed 2804

I am using Apollo Client (3.3.16) MockedProvider and Jest + react testing library to test a component which using useLazyQuery with onCompleted attribute. However, MockedProvider cannot call the onCompleted function (handleData() in my case). After the console.log I found that the onCompleted function has never been triggered. Any ideas how to test component ( in my case) with useLazyQuery? Appreciated in advance! My react component code is like this:

const handleData = data => { // this function never been called for testing
    setData(data.dataWithFilters.data);
  };

  const [loadData, { loading }] = useLazyQuery(
    GET_DATA,
    {
      variables: {
        id: productId,
        first: 999999,
        page: 1,
        isBase: true
      },
      onCompleted: handleData, // never been triggered for testing
      fetchPolicy: "network-only"
    }
  );

  useEffect(() => { // works fine
    loadData({
       variables: {
        id: productId,
        first: 999999,
        page: 1,
        isBase: true
      },
      fetchPolicy: "network-only"
    });
  }, [loadData, productId]); 

My testing code is:

 const renderComponent = (mocksData) => {
    render(
      <MockedProvider
        mocks={mocksData}
        defaultOptions={{
          query: { fetchPolicy: "no-cache" },
          watchQuery: { fetchPolicy: 'no-cache' },
        }}
        addTypename={false}
      >
        <ServicesContextProvider freightRateServices={{}}>
          <ContractInformationPageProvider>
            <MemoryRouter initialEntries={["contracts/311"]}>
              <Route path="products/:productId">
                <ContractInformationPage />
              </Route>
            </MemoryRouter>
          </ContractInformationPageProvider>
        </ServicesContextProvider>
      </MockedProvider>,
      {
        wrapper: BrowserRouter
      }
    );
  };
1 Answers

I was facing the same issue. Unfortunately when you test your code the way Apollo recommends, 9 out 10 times the tests fail because the mocked response does NOT match the query your production code is executing. As they say in then docs:

Your test must execute an operation that exactly matches a mock's shape and variables to receive the associated mocked response.

Even if your mock is 98% close, and just off by one field, you will not recieve any data in the test. Even worse is that you will not be aware of this because it will not log an error, it will just leave your data fields undefined. So watch very very close what the query fields and variables are and compare to the mock you made.

Related