免责声明;我对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标签。
有没有办法使这种类型的测试结构起作用?我不喜欢将所有内容都放在一个测试中的想法,更不用说组件的安装代码了。
谢谢!
答案 0 :(得分:0)
我不确定这是否是最好的方法,但是我想我找到了一种解决方法。
首先,空数组/加载问题不是问题;我可以追溯到测试库重置/重新渲染两次之间的组件。
这就是我所做的:
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()。
我对来自具有测试库经验的任何人的反馈非常感兴趣。似乎比我拥有的要好,但是我想确保它确实是最好的方法。
谢谢。