我已经解决这个问题好几天了,我相信我已经接近解决这个问题了。我正在尝试模拟在我的useEffect中触发的API调用。
useEffect(() => {
getAdminOrg();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const getAdminOrg = () => {
const token = localStorage.getItem("token");
const URL = `organizations/organizations/`;
let config = {
headers: { Authorization: "JWT " + token }
};
axios
.get(URL, config)
.then(response => {
setOrgTitle(response.data.name);
})
.catch(error => {
if (error.response) {
console.log(error.response);
if (error.response.status === 401) {
props.renewToken();
}
}
});
};如果setOrgTitle钩子运行,我将能够通过更改文本字段来检测到这一点。我试着在这里测试一下:
it("mocks API call", done => {
const wrapper = mount(
<OrganizationDocs />
);
const mock = new MockAdapter(axios);
mock
.onGet(`organizations/organizations/`, {
headers: { Authorization: "JWT1111" }
})
.reply(200, response.data);
setImmediate(() => {
wrapper.update();
expect(findByTestId(wrapper, "org-docs-header").text()).toContain(
organizationsOrganizations[0].name
);
done();
});
});当我运行测试时,我收到了未处理的promise rejection警告。此外,当我尝试通过控制台记录wrapper时,我可以看到API调用没有使用我正在应用的test头,所以我非常确定API调用没有使用我的mock。
任何帮助都将不胜感激。
发布于 2019-12-18 12:27:12
这里是仅使用jestjs + enzyme + react-dom/test-utils的单元测试解决方案。
例如。
index.ts
import React, { useEffect, useState } from 'react';
import axios from 'axios';
export const OrganizationDocs = (props) => {
const [orgTitle, setOrgTitle] = useState('');
useEffect(() => {
getAdminOrg();
}, []);
const getAdminOrg = () => {
const token = localStorage.getItem('token');
const URL = `organizations/organizations/`;
let config = {
headers: { Authorization: 'JWT ' + token },
};
axios
.get(URL, config)
.then((response) => {
setOrgTitle(response.data.name);
})
.catch((error) => {
if (error.response) {
console.log(error.response);
if (error.response.status === 401) {
props.renewToken();
}
}
});
};
return <div className="org-docs-header">orgTitle: {orgTitle}</div>;
};index.spec.ts
import React from 'react';
import { OrganizationDocs } from '.';
import { mount } from 'enzyme';
import axios from 'axios';
import { act } from 'react-dom/test-utils';
const mLocalStorage = {
_storage: {},
getItem: jest.fn((key) => {
return mLocalStorage._storage[key];
}),
setItem: jest.fn((key, value) => {
mLocalStorage._storage[key] = value;
}),
};
Object.defineProperty(window, 'localStorage', {
value: mLocalStorage,
});
describe('MyComponent', () => {
afterEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
});
it('mocks API call', async () => {
const token = 'JWT1111';
mLocalStorage.setItem('token', token);
const response = { data: { name: 'mocked name' } };
jest.spyOn(axios, 'get').mockResolvedValueOnce(response);
const wrapper = mount(<OrganizationDocs />);
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0));
});
expect(wrapper.find('.org-docs-header').text()).toContain('mocked name');
expect(axios.get).toBeCalledWith('organizations/organizations/', {
headers: { Authorization: 'JWT ' + token },
});
});
});单元测试结果和覆盖率报告:
PASS src/stackoverflow/59379085/index.spec.tsx (9.958s)
MyComponent
✓ mocks API call (85ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 78.95 | 0 | 80 | 76.47 | |
index.tsx | 78.95 | 0 | 80 | 76.47 | 23,24,25,26 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 11.427s源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59379085
https://stackoverflow.com/questions/59379085
复制相似问题