Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Example of how to test a component that uses useQuery?

I have a React component that uses the Apollo hooks lib's useQuery hook. I'm having trouble testing this component. Here is my current setup.

import React from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import DashboardBar from './DashboardBar';
import { render, cleanup } from '@testing-library/react';
import { QUERY } from '../../queries';
import { ApolloClient } from 'apollo-client';
import { ApolloProvider as ApolloHooksProvider } from '@apollo/react-hooks';
import { MockedProvider } from 'react-apollo/test-utils';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { MockLink } from 'apollo-link-mock';
import wait from 'waait';
import casual from 'casual';

describe('<DashboardBar />', () => {
  it('renders and matches snapshot', async () => {
    const mocks = [
      {
        request: { query: QUERY, variables: { id: 'WLYhM' } },
        result: {
          data: {
            q: {
              brand: fakeBrand,
              claimByAction: casual.boolean,
              claimRules: fakeClaimRules,
              wantIn: fakeWantIn,
            },
          },
        },
      },
    ];

    function createClient(mocks) {
      return new ApolloClient({
        cache: new InMemoryCache(),
        link: new MockLink(mocks),
      });
    }

    const client = createClient(mocks);

    const { container } = render(
      <ApolloHooksProvider client={client}>
        <Router>
          <DashboardBar {...props} store={reduxStore.store} />
        </Router>
      </ApolloHooksProvider>
    );

    console.log(container.firstChild);
    expect(container.firstChild).toBe(null);

    await wait(200);

    console.log(container.firstChild);
  });
});

When I run the test, I'm getting the following error

TypeError: Cannot read property 'q' of undefined

Even though the data is being returned fine in the actual component.

Does anyone have an example of how the successfully set up and executed tests w/ components using hooks from the Apollo hooks lib?

Thanks!

like image 269
maxwellgover Avatar asked Jul 16 '19 15:07

maxwellgover


People also ask

How do you test a component using a hook?

If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote. To reduce the boilerplate, we recommend using React Testing Library which is designed to encourage writing tests that use your components as the end users do.

How do you test a component React?

There are a few ways to test React components. Broadly, they divide into two categories: Rendering component trees in a simplified test environment and asserting on their output. Running a complete app in a realistic browser environment (also known as “end-to-end” tests).

How do you test a component in React native?

We can write a test to determine whether the Button component renders properly: // __tests__ import * as React from "react"; import Button from "../Button"; import renderer from "react-test-renderer"; it(`renders correctly`, () => { const tree = renderer.


1 Answers

Actually I managed to get this working using act()

Example as follows:

import { MockedProvider } from '@apollo/react-testing'
import query from 'data/graphql/Device/psaButton.graphql'
import React from 'react'
import { act, create, ReactTestRenderer } from 'react-test-renderer'
import { MockAppNoLayout } from 'testHelpers/testHelpers'
import waitForExpect from 'wait-for-expect'
import PSAButton from './PSAButton'

const mocks = [
  {
    request: {
      query,
      variables: {
        deviceId: '1',
      },
    },
    result: {
      data: {
        deviceById: {
          id: '1',
          info: {
            psaUrl: 'asdsadsad',
            lastSyncDate: 'asdasd',
            lastVerifyDate: 'asdsad',
          },
        },
        user: {
          timeZone: 'Europe/London',
        },
      },
    },
  },
]

describe('PSAButton', () => {
  it('renders correctly', async () => {
    let wrapper: ReactTestRenderer
    act(() => {
      wrapper = create(
        <MockAppNoLayout>
          <MockedProvider mocks={mocks} addTypename={false}>
            <PSAButton deviceId="1" />
          </MockedProvider>
        </MockAppNoLayout>,
      )
    })

    await waitForExpect(() => {
      const testInstance = wrapper.root
      expect(testInstance.findByType('span').children[0]).toBe('Open In PSA')
    })
  })
})

MockAppNoLayout is a React component tree containing amock IntlProvider and Styleprovider and the such like, (not important for this question).

like image 99
Damian Green Avatar answered Nov 15 '22 02:11

Damian Green