reactjs - 使用 Jest 进行测试时如何用模拟替换 React 组件
问题描述
在我正在从事的项目中,我真的被困在这个问题上,我发现的所有答案似乎都很简单,但它们对我没有用。也许我真的不明白什么是模拟,我真的可以使用一些指导。
我正在测试一个父组件,它有一个使用 GraphQL 从数据库中获取一些数据的子组件。在测试父母时,我不在乎孩子在做什么。我想用一个模拟组件(一个不从数据库中获取数据的组件)替换子组件,以便我只能专注于父组件。
我想出了一个最简单的例子来说明我的情况。请注意,我使用的是 React Native 和 React Native 测试库。
./src/ParentComponent.js
import React from 'react';
import { Text, View } from 'react-native';
import ChildComponent from './ChildComponent';
const ParentComponent = () => (
<View>
<Text>Hello World</Text>
<ChildComponent />
</View>
);
export default ParentComponent;
./src/ChildComponent.js
import React from 'react';
import { useQuery } from 'react-apollo';
import { View, Text } from 'react-native';
import gql from 'graphql-tag';
const CURRENT_USER_QUERY = gql`
query {
currentUser {
username
}
}
`;
const ChildComponent = () => {
const { data } = useQuery(CURRENT_USER_QUERY);
const { username } = data.currentUser;
return (
<View>
<Text>Welcome, {username}</Text>
</View>
);
};
export default ChildComponent;
./src/__mocks__/ChildComponent.js
import React from 'react';
import { Text } from 'react-native';
const ChildComponent = () => <Text>Welcome.</Text>;
export default ChildComponent;
./src/ParentComponent.test.js
import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import { render } from '@testing-library/react-native';
import ParentComponent from '../ParentComponent';
it(`should render the parent component.`, () => {
jest.mock('../ChildComponent');
const { getByText } = render(
<MockedProvider>
<ParentComponent />
</MockedProvider>
);
expect(getByText('Hello World')).toBeTruthy();
});
当我运行测试时,我收到以下错误...
● should render the parent component.
TypeError: Cannot read property 'currentUser' of undefined
14 | const ChildComponent = () => {
15 | const { data } = useQuery(CURRENT_USER_QUERY);
> 16 | const { username } = data.currentUser;
| ^
17 |
18 | return (
19 | <View>
at ChildComponent (src/ChildComponent.js:16:29)
它仍在使用真实的<ChildComponent />
. 为什么它不替换目录<ChildComponent />
中的模拟版本__mocks__
?这不是模拟的工作方式吗?如果有人可以请帮助和解释,将不胜感激。谢谢你。
解决方案
在为此绞尽脑汁几天之后,我终于弄清楚出了什么问题。我在it
声明中调用了模拟。当我将线 ,jest.mock('../ChildComponent');
移到顶部时,一切正常。所以,测试文件应该是这样的......
import React from 'react';
import { MockedProvider } from '@apollo/react-testing';
import { render } from '@testing-library/react-native';
import ParentComponent from '../ParentComponent';
jest.mock('../ChildComponent');
it(`should render the parent component.`, () => {
const { getByText } = render(
<MockedProvider>
<ParentComponent />
</MockedProvider>
);
expect(getByText('Hello World')).toBeTruthy();
});
推荐阅读
- java - 使用并发时超出时间限制
- python - 如何使用星体包将日落和日出数据的结果转换为数据框?
- python - 在训练测试拆分后使用 LabelEncoder 在分类变量中编码看不见/新的标签?
- python - 数据框不按日期排序
- c# - Autofac 在 MediatR 处理程序完成工作之前处理我的 DbContext
- django - Django 3.2 `get_asgi_application` 不能替代通道 AsgiHandler
- c++ - 使用 AVX-512 的两组 SIMD 矢量交集:需要加速
- laravel - 在 Laravel 8 中持久化数组数据
- python - 使用 Python pandas 从另一列驱动列
- docker - 在 Dockerfile 中复制动态传递的位置