gpt4 book ai didi

javascript - 如何使用 Jest 和 enzyme 测试异步数据获取 react 组件?

转载 作者:行者123 更新时间:2023-12-04 10:48:36 25 4
gpt4 key购买 nike

我有一个 React 组件,它使用 useEffect 钩子(Hook)来获取数据并相应地设置加载、成功和失败状态。

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;

我正在尝试使用 jest 和 enzyme 测试这个组件。

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

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

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

最佳答案

这是单元测试解决方案:

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

关于javascript - 如何使用 Jest 和 enzyme 测试异步数据获取 react 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59586141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com