reactjs - 使用 jest 在 componentDidMount 中反应测试 axios 获取请求
问题描述
我是 React 测试的新手,我正在尝试使用 axios 测试来自后端调用的 get 请求。
组件:
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
stockData: [],
}
}
componentDidMount() {
axios.get("http://localhost:8080/stocks")
.then(response => {
this.setState({
stockData: response.data
})
})
}
render() {
return (
<ChildComponent stockData={this.state.stockData}/>
)
}
}
从调用中获取的数据如下所示:
stockData: [
{
"ticker": "AAPL",
"name": "Apple Inc",
"priceChanges": {
"daily": 1.55,
"weekly": -3.55,
"monthly": -20.00
},
"financialData": {
"roa": 5.74,
"roe": 20.07,
"market_cap": "1.2T"
}
},
{
"ticker": "MSFT",
"name": "Microsoft Corporation",
"priceChanges": {
"daily": 4.35,
"weekly": 1.25,
"monthly": -22.05
},
"financialData": {
"roa": 8.73,
"roe": 15.07,
"market_cap": "1.3T"
}
}
//and many other similar objects
]
我读过我不应该真正使用真正的获取请求,而是使用一些“模拟”数据,但不知道如何实现它。我尝试了以下方法,但我不确定这是否是正确的方法。另外,我收到一个错误:TypeError: Cannot read property 'then' of undefined
test('should fetch company', () => {
const wrapper = shallow(<ParentComponent/>);
const resp = {stockData: [
{
"ticker": "AAPL",
"name": "Apple Inc",
"priceChanges": {
"daily": 1.55,
"weekly": -3.55,
"monthly": -20.00
},
"financialData": {
"roa": 5.74,
"roe": 20.07,
"market_cap": "1.2T"
}
}
};
wrapper.instance().componentDidMount().then(resp => {
expect(wrapper.state('stockData')).toContain(resp.stockData);
});
});
解决方案
您可以使用jest.spyOn(object, methodName)来模拟axios.get
方法及其解析值。由于axios.get
是异步操作,我们需要等到它完成。
例如
parent.jsx
:
import React from 'react';
import { ChildComponent } from './child';
import axios from 'axios';
export class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
stockData: [],
};
}
componentDidMount() {
axios.get('http://localhost:8080/stocks').then((response) => {
this.setState({ stockData: response.data });
});
}
render() {
return <ChildComponent stockData={this.state.stockData} />;
}
}
child.jsx
:
import React, { Component } from 'react';
export class ChildComponent extends Component {
render() {
return <div></div>;
}
}
parent.test.jsx
:
import { ParentComponent } from './parent';
import { shallow } from 'enzyme';
import axios from 'axios';
import React from 'react';
import { act } from 'react-dom/test-utils';
const whenStable = async () => {
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0));
});
};
describe('61465031', () => {
it('should pass', async () => {
const mResponse = { data: ['a', 'b'] };
const getSpy = jest.spyOn(axios, 'get').mockResolvedValueOnce(mResponse);
const wrapper = shallow(<ParentComponent></ParentComponent>);
await whenStable();
expect(wrapper.find('ChildComponent').prop('stockData')).toEqual(['a', 'b']);
getSpy.mockRestore();
});
});
带有覆盖率报告的单元测试结果:
PASS stackoverflow/61465031/parent.test.jsx (11.345s)
61465031
✓ should pass (20ms)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 95.45 | 100 | 85.71 | 94.12 |
child.jsx | 85.71 | 100 | 50 | 80 | 5
parent.jsx | 100 | 100 | 100 | 100 |
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 12.876s
源代码:https ://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61465031
推荐阅读
- r - R 旋转到宽并返回到长(多组)
- javascript - 如何以原生分辨率在 Android 上显示网页
- algorithm - 三边三角形的面积
- winapi - 为什么有些账户可以自动登录有些账户不能?
- javascript - 如何暂停和取消暂停属性以便在 knockout.js 中按预期工作
- mysql - 如何在 MySQL 中使用 substring_index 列出表拆分字符串值?
- python - 如何从此列表中检索数据
- c# - 如何修复剑道网格日期时间格式取决于当地时间
- r - 使用 hchart() 和 data_to_sankey() 函数创建 Sankey 图时出现显示问题
- python - Keras LSTM 参数说明