我已经实现了以下获取和测试用例,但这给了我错误(我在单元测试中很差)。
Main.js
import React, { Component } from 'react';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
testData: [],
}
}
componentDidMount() {
fetch(`http://testurl.com/testData`)
.then(response => response.json())
.then(result => this.setState({ testData: result }));
}
render() {
const {testData} = this.state;
return (
<div className="main">
{ testData.data &&
<section>
<CustomComponent movies={ testData.data } />
</section>
}
</div>
);
}
}
export default Main;
Main.test.js
import React from 'react';
import ReactDOM from 'react-dom';
import { mount, shallow } from 'enzyme';
import { fetchMock } from 'fetch-mock';
import Main from "../src/Main";
import testData from './_mockData_/testData'
it('should render without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<Main />, div);
ReactDOM.unmountComponentAtNode(div);
});
describe('should renders Main correctly', () => {
fetch('http://testurl.com/testData').then(res => {
expect(res.data).toEqual(testData)
})
});
即使我尝试使用http://www.wheresrhys.co.uk/fetch-mock/,也没有任何效果。
describe('should renders Main correctly', () => {
fetchMock.get('http://testurl.com/testData').then(res => {
expect(res.data).toEqual(testData)
})
});
总是出现以下错误。
参考错误:提取未定义
任何帮助将不胜感激。
已编辑:
根据评论,我按如下方式编辑了代码,但没有运气。
import testData from './_mockData_/testData'
describe('Main', () => {
it('renders without crashing', () => {
const tree = shallow(<Main />);
expect(tree).toMatchSnapshot();
});
beforeEach(() => {
fetch.resetMocks()
})
it('calls API and returns data to me', () => {
fetch.mockResponseOnce(JSON.stringify({ someData: testData }))
//assert on the response
fetch(`http://testurl.com/testData`).then(res => {
expect(res.data).toEqual(testData)
})
//assert on the times called and arguments given to fetch
expect(fetch.mock.calls.length).toEqual(1)
expect(fetch.mock.calls[0][0]).toEqual('http://testurl.com/testData')
})
});
出现以下错误:
TypeError:无法读取未定义的属性'then'
答案 0 :(得分:0)
这是仅使用enzyme
v3和jestjs
的解决方案,仅此而已。
main.tsx
:
import React, { Component } from 'react';
import { CustomComponent } from './CustomComponent';
import fetch from 'node-fetch';
interface IMainState {
testData: {
data: any[];
};
}
class Main extends Component<any, IMainState> {
constructor(props) {
super(props);
this.state = {
testData: {
data: []
}
};
}
public componentDidMount() {
fetch(`http://testurl.com/testData`)
.then(response => response.json())
.then(result => this.setState({ testData: result }));
}
public render() {
const { testData } = this.state;
return (
<div className="main">
{testData.data && (
<section>
<CustomComponent movies={testData.data} />
</section>
)}
</div>
);
}
}
export default Main;
单元测试:
main.spec.tsx
:
import React from 'react';
import { shallow } from 'enzyme';
import Main from './main';
import fetch from 'node-fetch';
const { Response } = jest.requireActual('node-fetch');
jest.mock('node-fetch');
describe('Main', () => {
it('t1', done => {
(fetch as jest.MockedFunction<typeof fetch>).mockResolvedValueOnce(
new Response(
JSON.stringify({
data: ['data1', 'data2']
})
)
);
const wrapper = shallow(<Main></Main>);
expect(fetch).toBeCalledWith(`http://testurl.com/testData`);
expect(wrapper).toMatchSnapshot();
setImmediate(() => {
expect(wrapper.state()).toEqual({
testData: {
data: ['data1', 'data2']
}
});
expect(wrapper).toMatchSnapshot();
done();
});
});
});
具有覆盖范围的单元测试结果:
PASS src/stackoverflow/53788454/main.spec.tsx (5.517s)
Main
✓ t1 (28ms)
› 1 snapshot written.
---------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------|----------|----------|----------|----------|-------------------|
All files | 95.83 | 100 | 87.5 | 95.24 | |
CustomComponent.tsx | 85.71 | 100 | 50 | 83.33 | 9 |
main.tsx | 100 | 100 | 100 | 100 | |
---------------------|----------|----------|----------|----------|-------------------|
Snapshot Summary
› 1 snapshot written from 1 test suite.
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 1 written, 1 passed, 2 total
Time: 6.515s
组件快照:
// Jest Snapshot v1
exports[`Main t1 1`] = `
<div
className="main"
>
<section>
<CustomComponent
movies={Array []}
/>
</section>
</div>
`;
exports[`Main t1 2`] = `
<div
className="main"
>
<section>
<CustomComponent
movies={
Array [
"data1",
"data2",
]
}
/>
</section>
</div>
`;
以下是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/53788454
关于如何手动模拟node-fetch
,请看一下https://jestjs.io/docs/en/bypassing-module-mocks