我是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
]
我已经读到我不应该真正使用真正的get请求,而应该使用一些“模拟”数据,但是不知道如何实现它。我已经尝试了以下方法,但是我不确定这是否是正确的方法。另外,我得到一个错误: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);
});
});
答案 0 :(得分:1)
您可以使用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