reactjs - 如何在反应中使用 API 调用测试组件?
问题描述
我在测试从 API 获取数据并在屏幕上呈现的反应组件时遇到问题。这是我得到的错误。
● Company Details › renders company details with given data
expect(received).toMatch(expected)
Expected substring: "Google"
Received string: "no name provided"
18 | );
19 |
> 20 | expect(getByTestId('company-name').textContent).toMatch('Google');
| ^
21 | expect(getByTestId('sponsors-visa').textContent).toMatch('Yes');
22 | expect(getByTestId('description').textContent).toMatch('this is a company description');
23 | });
at Object.<anonymous> (src/tests/components/company-detail/CompanyDetail.test.js:20:53)
我的测试文件CompanyDetail.test.js
代码:
import React from 'react';
import CompanyDetail from '../../../components/company-detail/CompanyDetail';
import { BrowserRouter } from 'react-router-dom';
import { render } from '@testing-library/react';
describe('Company Details', () => {
let mockData;
beforeEach(() => {
mockData = { match: { params: { id: 4 } } };
jest.mock('../../../components/effects/use-fetch.effect');
});
it('renders company details with given data', async () => {
const { getByTestId } = render(
<BrowserRouter>
<CompanyDetail {...mockData} />,
</BrowserRouter>
);
expect(getByTestId('company-name').textContent).toMatch('Google');
expect(getByTestId('sponsors-visa').textContent).toMatch('Yes');
expect(getByTestId('description').textContent).toMatch('this is a company description');
});
});
我要测试的代码 ( CompanyDetail.js
)
import CONSTANTS from '../../constants/constants';
import { Link } from 'react-router-dom';
import useFetch from '../effects/use-fetch.effect';
const CompanyDetail = (props) => {
const { id } = props.match.params;
const { name, description, jobs, known_to_sponsor_visa } = useFetch(`${CONSTANTS.BASE_URL}/companies/${id}`);
return (
<React.Fragment>
<Container>
<Row className="m-2">
<Col>
<Card>
<Card.Body>
<Card.Title>
<h3 data-testid="company-name">{name ? name : 'no name provided'}</h3>
</Card.Title>
<Card.Text data-testid="sponsors-visa">
<b>Known to sponsor work visa: </b>
{known_to_sponsor_visa ? known_to_sponsor_visa : 'No data'}
</Card.Text>
<Card.Text data-test-id="description">{description}</Card.Text>
</Card.Body>
</Card>
</Col>
</Row>
</Container>
</React.Fragment>
);
};
export default CompanyDetail;
以防万一,如果它需要use-fetch.effect.js
:
import { useState, useEffect } from 'react';
const useFetch = (url) => {
const [dataArray, setData] = useState([]);
useEffect(() => {
try {
const fetchData = async () => {
const res = await fetch(url);
const dataArray = await res.json();
setData(dataArray.data)
}
fetchData();
} catch (err) {
console.error(err);
}
}, [url]);
return dataArray;
};
export default useFetch;
我可以通过 props 发送数据来测试它,但我不知道如何模拟数据来测试该 url 以接收 id 并将其呈现到特定位置。任何帮助,将不胜感激。我知道为什么会出现错误,因为我没有通过任何公司名称作为 Google 进行检查。问题是我如何通过传递一些虚拟数据来测试它。
解决方案
由于useFetch
预计会以任何方式异步,这可能会影响组件的工作方式,因此它需要以比返回值的 Jest spy 更复杂的方式进行模拟。请求本身可以被模拟而不是整个useFetch
:
let data = { name: 'Google', ... };
spyOn(global, 'fetch').mockResolvedValue({ json: jest.fn().mockResolvedValue({ data }) });
...
expect(getByTestId('company-name').textContent).toMatch('no name provided');
await waitFor(() => expect(getByTestId('company-name').textContent).toMatch('Google'));
推荐阅读
- django - Django Rest Framework Jwt + 路由器
- c# - MailBee Imap.Connect 引发算术运算导致溢出错误
- odoo - Odoo 14 CE 中的可选依赖项
- php - 为什么无法将二维码图像保存到服务器的文件夹中?
- vue.js - 无法解析模块说明符“@vue/composition-api”。相对引用必须以“/”、“./”或“../”开头
- python - 熊猫没有将两个不同的列信息匹配在一起
- node.js - 在猫鼬中找到所有
- c# - EF Core 调用具有多个连接的存储过程并映射相关数据
- apache-spark - 为什么 Spark 结构化流 org.apache.spark.sql.functions.input_file_name 返回空白文件名
- laravel - Laravel 8 从下到上的路线顺序