Apollo MockedProvider 测试问题(我渲染的组件不断消失)

Apollo MockedProvider testing issues (my rendered component keeps disappearing)

免责声明;我对 react-testing-library(一直在使用公认的旧版 Enzyme)和 Apollo Query/MockedProvider 组件(一直在通过 JS 服务对象使用客户端)有点陌生,所以这可能是一个愚蠢的问题...

我有一个组件接收我尝试为其编写测试的国家/地区列表。我想做的是:

import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import { render, act } from '@testing-library/react';
import wait from 'waait';
import Countries, { countryQuery } from './Countries';
import { isTerminating } from 'apollo-link/lib/linkUtils';

const mockCountryName = 'sample country';
const mocks = [
  {
    request: {
      query: countryQuery,
      vairables: {},
    },
    result: {
      data: {
        countries: [{ name: mockCountryName }],
      },
    },
  },
];

describe('when working with the countries component', () => {
  describe('and the component is loading', () => {
    let component;

    beforeAll(async (done) => {
      await act(async () => {
        component = render(
          <MockedProvider mocks={[]}>
            <Countries />
          </MockedProvider>
        );
      });
      done();
    });

    it('should have a title', () => {
      expect(component.getByText('Countries Component')).not.toBeUndefined();
    });

    it('should have a loading status', () => {
      expect(component.getByText('Loading...')).not.toBeUndefined();
    });
  });
});

当它运行时,第二个测试(关于加载状态)失败了,因为此时组件看起来只是一个 body 标签。我尝试将 beforeAll 更改为 beforeEach,但这只会生成一个具有错误指示器的组件。我在我的组件中放置了一些 console.log 语句,这就是它们向我展示的内容:

console.log src/components/Countries.js:45
      Loading is: true
    console.log src/components/Countries.js:46
      Error is: undefined
    console.log src/components/Countries.js:45
      Loading is: false
    console.log src/components/Countries.js:46
      Error is: Error: Network error: No more mocked responses for the query: {
        countries {
          name
          phone
          __typename
        }
      }
      , variables: {}

我想知道它是否不喜欢作为 MockedProvider 的模拟 属性 传入的空数组。但是我见过的每个例子都是这样做的,所以...

作为一项实验,我向规范文件添加了第二组测试,以查看是否只是导致该问题的组件存在奇怪的时序问题。这是第二个测试:

describe('and the component has data', () => {
    let component;

    beforeAll(async (done) => {
      await act(async () => {
        component = render(
          <MockedProvider mocks={mocks} addTypename={false}>
            <Countries />
          </MockedProvider>
        );
        await wait(0);
      });
      done();
    });

    it('should have a title', () => {
      expect(component.getByText('Countries Component')).not.toBeUndefined();
    });

    it('should have a loading status', () => {
      expect(component.getByText(mockCountryName)).not.toBeUndefined();
    });
  });

这个也有同样的问题;第一个测试有效(如果我重新排序测试,第一个总是有效)但第二个失败,组件似乎是一个空的 body 标签。

有没有办法使这种类型的测试结构起作用?我不喜欢必须将所有内容都放在一个测试中的想法,更不用说组件的设置代码了。

谢谢!

我不确定这是否是最佳方法,但我想我找到了解决方法。

首先,空白 array/loading 问题不是问题;我将所有内容都追溯到 testing-library resetting/re-rendering 测试之间的组件。

这是我所做的:

describe('and the component is loading', () => {
    let component, pageTitle, loadingMessage;

    beforeAll(async (done) => {
      await act(async () => {
        component = render(
          <MockedProvider mocks={[]}>
            <Countries />
          </MockedProvider>
        );
        pageTitle = component.getByText(mockPageTitle);
        loadingMessage = component.getByText(mockLoadingMessage);
      });
      done();
    });

    it('should have a title', () => {
      expect(pageTitle).not.toBeUndefined();
    });

    it('should have a loading status', () => {
      expect(loadingMessage).not.toBeUndefined();
    });
  });

我没有尝试在每个测试中调用 component.getTextBy,而是将它们移到 beforeAll 中,并将输出分配给变量。每个测试都使用变量进行测试。我还为我的 Routes 组件编写了一个测试,我仍然能够在组件上调用 fireEvent.click()。

我对任何在测试库方面对此有更多经验的人的任何反馈都非常感兴趣。它似乎比我拥有的更好,但我想确保它确实是最好的方法。

谢谢。