reactjs - 如何在 react 中使用 API 调用测试组件?

标签 reactjs jestjs fetch react-hooks react-testing-library

我在测试从 API 获取数据并在屏幕上呈现的 React 组件时遇到问题。
这是我得到的错误。

     ● 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'));

关于reactjs - 如何在 react 中使用 API 调用测试组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62134212/

相关文章:

javascript - 根据 React 中的键更新状态

javascript - 在样式组件中设置变量

javascript - React 中的 JSON 解析嵌套对象

javascript - 使用 fetch(),从非 HTTP OK 状态代码中读取响应主体并捕获异常

node.js - 使用 Mocha 测试 React 组件 : unexpected token

reactjs - (ESLint) 在 VS 2017 React 项目中找不到模块 'eslint-config-react-app'

reactjs - 获取断点以使用 jest、Visual Studio 代码和自定义 typescript 转换器

javascript - 如何正确地 mock `antd` Upload Dragger?

javascript - 如何在 if 条件下增加 for-in 循环中 jest 的分支覆盖率?

git - 为什么 `git show-ref FETCH_HEAD` 是空的?