如何使用 JEST 和 REACT 解决 axios 模拟错误
How to resolve axios mocking errors using JEST and REACT
已使用 axios 模拟方法创建了单元测试用例,并确实看到了以下控制台错误。尝试了很多方法,但 none 解决了问题。 REACT/JEST 社区的新手,但正在尽力解决这个问题。
期望:
- 应该 100% 覆盖所有测试用例,包括成功、错误场景,并且应该在没有 warnings/errors.
的情况下通过
- 应使用空结果列表和非空结果列表测试响应。
- 还应处理由于 timeout/network 引起的错误情况。
错误:
Expected: undefined
Received: {"results": []}
(node:76675) UnhandledPromiseRejectionWarning:
Unhandled promise rejection. This error originated
either by throwing inside of an async function without a catch block,
or by rejecting a promise which was not handled with .catch().
(rejection id: 1)
(node:76675) [DEP0018] DeprecationWarning: Unhandled promise rejections
are deprecated. In the future, promise rejections that are not handled will
terminate the Node.js process with a non-zero exit code.
我尝试了什么:
index.js
export default getAreas = area => axios.get(`/test/areas/${area}`);
__mocks__/axios.js
const axiosMocked = {
get: jest.fn(() => Promise.resolve({ results: [] }))
};
export default axiosMocked;
__tests__/index.test.js
import mockAxios from 'axios';
import getAreas from '../index';
afterEach(() => {
jest.clearAllMocks();
});
it('fetches results from api', () => {
mockAxios.get.mockImplementationOnce(() => Promise.resolve({ results: [] }));
getAreas('atl').then(response => {
expect(response).toEqual();
});
expect(mockAxios.get).toHaveBeenCalledTimes(1);
expect(mockAxios.get).toHaveBeenCalledWith('/test/areas/atl');
});
这是一个使用jest.mock
方法手动模拟axios
而不使用任何第三方模拟库的解决方案。
index.ts
:
import axios from 'axios';
const getAreas = area => axios.get(`/test/areas/${area}`);
export default getAreas;
index.spec.ts
:
import getAreas from './';
import axios from 'axios';
jest.mock('axios');
afterEach(() => {
jest.clearAllMocks();
});
describe('getAreas', () => {
it('fetches results from api', () => {
(axios.get as jest.Mock).mockResolvedValueOnce({ results: [] });
getAreas('atl').then(response => {
expect(response).toEqual({ results: [] });
});
expect(axios.get).toHaveBeenCalledTimes(1);
expect(axios.get).toHaveBeenCalledWith('/test/areas/atl');
});
});
100% 覆盖率的单元测试结果:
PASS src/Whosebug/58357043/index.spec.ts (7.557s)
getAreas
✓ fetches results from api (9ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 8.952s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/Whosebug/58357043
已使用 axios 模拟方法创建了单元测试用例,并确实看到了以下控制台错误。尝试了很多方法,但 none 解决了问题。 REACT/JEST 社区的新手,但正在尽力解决这个问题。
期望:
- 应该 100% 覆盖所有测试用例,包括成功、错误场景,并且应该在没有 warnings/errors. 的情况下通过
- 应使用空结果列表和非空结果列表测试响应。
- 还应处理由于 timeout/network 引起的错误情况。
错误:
Expected: undefined
Received: {"results": []}
(node:76675) UnhandledPromiseRejectionWarning:
Unhandled promise rejection. This error originated
either by throwing inside of an async function without a catch block,
or by rejecting a promise which was not handled with .catch().
(rejection id: 1)
(node:76675) [DEP0018] DeprecationWarning: Unhandled promise rejections
are deprecated. In the future, promise rejections that are not handled will
terminate the Node.js process with a non-zero exit code.
我尝试了什么:
index.js
export default getAreas = area => axios.get(`/test/areas/${area}`);
__mocks__/axios.js
const axiosMocked = {
get: jest.fn(() => Promise.resolve({ results: [] }))
};
export default axiosMocked;
__tests__/index.test.js
import mockAxios from 'axios';
import getAreas from '../index';
afterEach(() => {
jest.clearAllMocks();
});
it('fetches results from api', () => {
mockAxios.get.mockImplementationOnce(() => Promise.resolve({ results: [] }));
getAreas('atl').then(response => {
expect(response).toEqual();
});
expect(mockAxios.get).toHaveBeenCalledTimes(1);
expect(mockAxios.get).toHaveBeenCalledWith('/test/areas/atl');
});
这是一个使用jest.mock
方法手动模拟axios
而不使用任何第三方模拟库的解决方案。
index.ts
:
import axios from 'axios';
const getAreas = area => axios.get(`/test/areas/${area}`);
export default getAreas;
index.spec.ts
:
import getAreas from './';
import axios from 'axios';
jest.mock('axios');
afterEach(() => {
jest.clearAllMocks();
});
describe('getAreas', () => {
it('fetches results from api', () => {
(axios.get as jest.Mock).mockResolvedValueOnce({ results: [] });
getAreas('atl').then(response => {
expect(response).toEqual({ results: [] });
});
expect(axios.get).toHaveBeenCalledTimes(1);
expect(axios.get).toHaveBeenCalledWith('/test/areas/atl');
});
});
100% 覆盖率的单元测试结果:
PASS src/Whosebug/58357043/index.spec.ts (7.557s)
getAreas
✓ fetches results from api (9ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 8.952s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/Whosebug/58357043