sur*_*wat 6 unit-testing node.js express jestjs
感谢您花时间阅读我的问题。
我对 Jest 和单元测试还很陌生,所以在开始为控制器功能编写单元测试之前,我想检查一下我的理解。如此高的水平,我理解单元测试是为了测试控制器函数在调用时是否按预期运行。
我将如何为以下代码编写 Jest 单元测试?我真的很感激一个例子,这样我就可以在为其他控制器编写笑话测试时参考它。谢谢。
//retrieveMember.js
const debug = require('debug')('get_member');
const MemberService = require('../services/MemberService');
const generateError = require('../lib/generateError');
const retrieveMember = async (req, res, next) => {
try {
if (req.params.id === ""
|| req.params.id === undefined) {
throw generateError(400, "invalid.");
}
const regex = RegExp("[^a-zA-Z0-9\-]");
if (regex.test(req.params.id)) {
throw generateError(400, "invalid format.");
}
const memberId = req.params.id;
const memberRecord = await MemberService.retrieveOneMember(memberId);
const member_detail = {
id: memberRecord.id,
username: memberRecord.username,
};
res.status(200).send({member_detail: member_detail});
} catch (e) {
if (e) {
debug('could not get member');
return next(e);
}
}
};
module.exports = retrieveMember;
Run Code Online (Sandbox Code Playgroud)
sli*_*wp2 17
这是单元测试解决方案:
\n\nretrieveMember.js:
const debug = console.debug;\nconst MemberService = require(\'./MemberService\');\nconst generateError = require(\'./generateError\');\n\nconst retrieveMember = async (req, res, next) => {\n try {\n if (req.params.id === \'\' || req.params.id === undefined) {\n throw generateError(400, \'invalid.\');\n }\n\n const regex = RegExp(\'[^a-zA-Z0-9-]\');\n if (regex.test(req.params.id)) {\n throw generateError(400, \'invalid format.\');\n }\n\n const memberId = req.params.id;\n const memberRecord = await MemberService.retrieveOneMember(memberId);\n\n const member_detail = {\n id: memberRecord.id,\n username: memberRecord.username,\n };\n\n res.status(200).send({ member_detail: member_detail });\n } catch (e) {\n if (e) {\n debug(\'could not get member\');\n return next(e);\n }\n }\n};\n\nmodule.exports = retrieveMember;\nRun Code Online (Sandbox Code Playgroud)\n\nMemberService.js:
const MemberService = {\n async retrieveOneMember() {\n return \'real data\';\n },\n};\n\nmodule.exports = MemberService;\nRun Code Online (Sandbox Code Playgroud)\n\ngenerateError.js:
function generateError(status, message) {\n return new Error(message);\n}\n\nmodule.exports = generateError;\nRun Code Online (Sandbox Code Playgroud)\n\nretrieveMember.test.js:
const retrieveMember = require(\'./retrieveMember\');\nconst MemberService = require(\'./MemberService\');\n\ndescribe(\'61834610\', () => {\n it(\'should throw 400 error if id is empty string\', async () => {\n const mReq = { params: { id: \'\' } };\n const mRes = {};\n const mNext = jest.fn();\n await retrieveMember(mReq, mRes, mNext);\n expect(mNext).toBeCalledWith(new Error(\'invalid.\'));\n });\n\n it(\'should throw 400 error if id is undefined\', async () => {\n const mReq = { params: {} };\n const mRes = {};\n const mNext = jest.fn();\n await retrieveMember(mReq, mRes, mNext);\n expect(mNext).toBeCalledWith(new Error(\'invalid.\'));\n });\n\n it(\'should throw 400 error if id is invalid format\', async () => {\n const mReq = { params: { id: \'$$\' } };\n const mRes = {};\n const mNext = jest.fn();\n await retrieveMember(mReq, mRes, mNext);\n expect(mNext).toBeCalledWith(new Error(\'invalid format.\'));\n });\n\n it(\'should retrieve one member by id and send response correctly\', async () => {\n const mMemberRecord = { id: \'1\', username: \'KF1\' };\n jest.spyOn(MemberService, \'retrieveOneMember\').mockResolvedValueOnce(mMemberRecord);\n const mReq = { params: { id: \'1\' } };\n const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };\n const mNext = jest.fn();\n await retrieveMember(mReq, mRes, mNext);\n expect(MemberService.retrieveOneMember).toBeCalledWith(\'1\');\n expect(mRes.status).toBeCalledWith(200);\n expect(mRes.send).toBeCalledWith({ member_detail: { id: \'1\', username: \'KF1\' } });\n });\n});\nRun Code Online (Sandbox Code Playgroud)\n\n带有覆盖率报告的单元测试结果:
\n\n PASS stackoverflow/61834610/retrieveMember.test.js (9.346s)\n 61834610\n \xe2\x9c\x93 should throw 400 error if id is empty string (18ms)\n \xe2\x9c\x93 should throw 400 error if id is undefined (2ms)\n \xe2\x9c\x93 should throw 400 error if id is invalid format (1ms)\n \xe2\x9c\x93 should retrieve one member by id and send response correctly (1ms)\n\n console.debug\n could not get member\n\n at stackoverflow/61834610/retrieveMember.js:27:7\n\n console.debug\n could not get member\n\n at stackoverflow/61834610/retrieveMember.js:27:7\n\n console.debug\n could not get member\n\n at stackoverflow/61834610/retrieveMember.js:27:7\n\n-------------------|---------|----------|---------|---------|-------------------\nFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n-------------------|---------|----------|---------|---------|-------------------\nAll files | 95.83 | 87.5 | 75 | 95.45 | \n MemberService.js | 66.67 | 100 | 0 | 66.67 | 3 \n generateError.js | 100 | 100 | 100 | 100 | \n retrieveMember.js | 100 | 87.5 | 100 | 100 | 26 \n-------------------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests: 4 passed, 4 total\nSnapshots: 0 total\nTime: 10.539s\nRun Code Online (Sandbox Code Playgroud)\n