Suc*_*ta 4 javascript unit-testing mocking jestjs axios
我正在尝试测试以下为 put/post 作为配置选项编写的 axios 请求:
export function saveCourse(course){
const config = {
method: course.id ? 'PUT' : 'POST',// POST for create, PUT to update when id already exists.
url: baseUrl + (course.id || ''),
headers: { "content-type": "application/json" },
data: course
}
return axios(config)
.then((res) => {
if(res.status === 201 || res.status === 200) return res.data;
if(res.status === 400){
const error = res.text();
throw new Error(error);
}
})
.catch((err) => console.log(err));
}
Run Code Online (Sandbox Code Playgroud)
courseApi.test.js 如下所示:
import { saveCourse } from './courseApi';
import axios from 'axios';
jest.mock('axios');
describe('check API calls', () => {
it('should update the course', () => {
let res = {
id: 10,
title: "Securing React Apps with Auth0",
slug: "react-auth0-authentication-security",
authorId: 2,
category: "JavaScript"
};
const config = {
method: 'put',
url: 'http://localhost:3001/courses/10',
headers: { "content-type": "application/json" },
data: res
}
}
axios = jest.fn().mockResolvedValue({
status: 200,
data: res
});
let result = await saveCourse(res);
expect(result).toEqual(res);
// expect(axiosMock.put).toHaveBeenCalledTimes(1);
});
});
Run Code Online (Sandbox Code Playgroud)
也尝试使用mockImplementationOnce,在这种情况下,模拟axios没有被调用。
it("save course scenario", async function () {
const course = {
id: 10,
title: "Securing React Apps with Auth0",
slug: "react-auth0-authentication-security",
authorId: 2,
category: "JavaScript"
};
axios.put.mockImplementationOnce(() => Promise.resolve(course));
expect(saveCourse(course)).resolves.toEqual(course);
expect(axios.put).toHaveBeenCalledTimes(1);
});
Run Code Online (Sandbox Code Playgroud)
抛出错误如下:
TypeError: Cannot read property 'then' of undefined
24 | data: course
25 | }
> 26 | return axios(config)
| ^
27 | .then((res) => {
28 | if(res.status === 201) { console.log(res); return res.data; }
29 | if(res.status === 200) { console.log(res); return res.data; }
at saveCourse (src/api/courseApi.js:26:10)
at Object.<anonymous> (src/api/courseApi.test.js:39:12)
Run Code Online (Sandbox Code Playgroud)
那么我应该如何解决这个问题,我错过了为 axios 模拟设置的任何内容?
提前致谢!
单元测试解决方案:
\n\nindex.js:
import axios from \'axios\';\n\nexport function saveCourse(course) {\n const baseUrl = \'http://example.com/\';\n const config = {\n method: course.id ? \'PUT\' : \'POST\',\n url: baseUrl + (course.id || \'\'),\n headers: { \'content-type\': \'application/json\' },\n data: course,\n };\n return axios(config)\n .then((res) => {\n if (res.status === 201 || res.status === 200) return res.data;\n if (res.status === 400) {\n const error = res.text();\n throw new Error(error);\n }\n })\n .catch((err) => console.log(err));\n}\nRun Code Online (Sandbox Code Playgroud)\n\nindex.test.js:
import { saveCourse } from \'./\';\nimport axios from \'axios\';\n\njest.mock(\'axios\', () => jest.fn());\n\ndescribe(\'60992357\', () => {\n afterEach(() => {\n jest.restoreAllMocks();\n });\n it(\'should return data if status code equals 200\', async () => {\n const mRes = { status: 200, data: \'fake data\' };\n axios.mockResolvedValueOnce(mRes);\n const actual = await saveCourse({ id: 1 });\n expect(actual).toEqual(\'fake data\');\n expect(axios).toBeCalledWith({\n method: \'PUT\',\n url: \'http://example.com/1\',\n headers: { \'content-type\': \'application/json\' },\n data: { id: 1 },\n });\n });\n\n it(\'should throw error if status code equals 400\', async () => {\n const mRes = { status: 400, text: jest.fn().mockReturnValue(\'network\') };\n axios.mockResolvedValueOnce(mRes);\n const logSpy = jest.spyOn(console, \'log\');\n const actual = await saveCourse({ id: 1 });\n expect(actual).toBeUndefined();\n expect(axios).toBeCalledWith({\n method: \'PUT\',\n url: \'http://example.com/1\',\n headers: { \'content-type\': \'application/json\' },\n data: { id: 1 },\n });\n expect(mRes.text).toBeCalledTimes(1);\n expect(logSpy).toBeCalledWith(new Error(\'network\'));\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n\n带有覆盖率报告的单元测试结果:
\n\n PASS stackoverflow/60992357/index.test.js (9.916s)\n 60992357\n \xe2\x9c\x93 should return data if status code equals 200 (7ms)\n \xe2\x9c\x93 should throw error if status code equals 400 (21ms)\n\n console.log node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866\n Error: network\n at /Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/stackoverflow/60992357/index.js:671:13\n at process._tickCallback (internal/process/next_tick.js:68:7)\n\n----------|---------|----------|---------|---------|-------------------\nFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n----------|---------|----------|---------|---------|-------------------\nAll files | 100 | 70 | 100 | 100 | \n index.js | 100 | 70 | 100 | 100 | 6,7,14 \n----------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests: 2 passed, 2 total\nSnapshots: 0 total\nTime: 11.848s\nRun Code Online (Sandbox Code Playgroud)\n\n源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60992357
\n| 归档时间: |
|
| 查看次数: |
8708 次 |
| 最近记录: |