如何通过玩笑和酶测试异步数据获取反应组件?

问题描述 投票:1回答:1

我有一个使用useEffect钩子的react组件,用于获取数据并相应地设置加载,成功和失败状态。

import React, { useState, useEffect } from "react";
import { fetchData } from "./api";

function App({ id }) {
  const [data, setData] = useState(null);
  const [isFetching, setIsFetching] = useState(false);
  const [error, setError] = useState(null);
  useEffect(() => {
    setIsFetching(true);
    fetchData(id)
      .then(
        response => {
          setData(response.data);
          setIsFetching(false);
        },
        err => {
          setError(err);
          setIsFetching(false);
        }
      )
      .catch(err => {
        setError(err);
        setIsFetching(false);
      });
  }, [id]);

  if (data) {
    return <pre>{JSON.stringify(data)}</pre>;
  }
  if (isFetching) {
    return <div>fetching...</div>;
  }
  if (error) {
    return <pre>{JSON.stringify(error)}</pre>;
  }
  return <div>null</div>;
}

export default App;

我正在尝试使用玩笑和酶来测试此组件。

这里是沙箱https://codesandbox.io/s/jest-enzyme-re41k

我收到一个奇怪的错误Cannot read property 'isTTY' of undefined

有人可以帮助修复测试吗?

javascript reactjs unit-testing jestjs enzyme
1个回答
0
投票

这里是单元测试解决方案:

app.jsx

import React, { useState, useEffect } from 'react';
import { fetchData } from './api';

function App({ id }) {
  const [data, setData] = useState(null);
  const [isFetching, setIsFetching] = useState(false);
  const [error, setError] = useState(null);
  useEffect(() => {
    setIsFetching(true);
    fetchData(id)
      .then(
        (response) => {
          setData(response.data);
          setIsFetching(false);
        },
        (err) => {
          setError(err);
          setIsFetching(false);
        },
      )
      .catch((err) => {
        setError(err);
        setIsFetching(false);
      });
  }, [id]);

  if (data) {
    return <pre>{JSON.stringify(data)}</pre>;
  }
  if (isFetching) {
    return <div>fetching...</div>;
  }
  if (error) {
    return <pre>{JSON.stringify(error)}</pre>;
  }
  return <div>null</div>;
}

export default App;

api.js

export function fetchData() {
  // real implementation
}

app.test.jsx

import App from './app';
import { mount } from 'enzyme';
import { fetchData } from './api';
import { act } from 'react-dom/test-utils';

jest.mock('./api.js', () => {
  return {
    fetchData: jest.fn(),
  };
});

describe('59586141', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });
  it('should fetch data correctly', async () => {
    const mResponse = { data: { id: 1 } };
    const mProps = { id: 1 };
    fetchData.mockResolvedValueOnce(mResponse);
    const wrapper = mount(<App {...mProps}></App>);
    expect(wrapper.exists).toBeTruthy();
    expect(wrapper.find('div').text()).toBe('fetching...');
    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 0));
    });
    wrapper.update();
    expect(wrapper.find('pre').text()).toBe(JSON.stringify(mResponse.data));
    expect(fetchData).toBeCalledWith(1);
  });

  it('should handle error if fetch data failure', async () => {
    const mError = new Error('some network error');
    const mProps = { id: 1 };
    fetchData.mockRejectedValueOnce(mError);
    const wrapper = mount(<App {...mProps}></App>);
    expect(wrapper.exists).toBeTruthy();
    expect(wrapper.find('div').text()).toBe('fetching...');
    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 0));
    });
    wrapper.update();
    expect(wrapper.find('pre').text()).toBe(JSON.stringify(mError));
    expect(fetchData).toBeCalledWith(1);
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59586141/api.test.jsx (9.079s)
  59586141
    ✓ should fetch data correctly (119ms)
    ✓ should handle error if fetch data failure (12ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |     93.1 |      100 |       80 |     91.3 |                   |
 app.jsx  |     93.1 |      100 |       80 |     91.3 |             22,23 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        10.458s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59586141

© www.soinside.com 2019 - 2024. All rights reserved.