如何测试使用useQuery的组件的示例?

时间:2019-07-16 15:33:58

标签: javascript reactjs react-hooks react-apollo react-apollo-hooks

我有一个React组件,它使用Apollo钩子库的useQuery钩子。我在测试此组件时遇到问题。这是我当前的设置。

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

运行测试时,出现以下错误

TypeError: Cannot read property 'q' of undefined

即使在实际组件中正常返回了数据。

有没有人举过一个例子,说明如何使用Apollo钩子库中的钩子成功建立和执行带有组件的测试?

谢谢!

1 个答案:

答案 0 :(得分:0)

实际上,我设法使用act()

示例如下:

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是一个React组件树,其中包含amock IntlProviderStyleprovider之类的东西(对这个问题并不重要)。