我试图找出article.controller.js 文件测试失败的原因。但是,找不到原因。
[文件:article.controller.js]
const {
saveArticle
} = require('../services/article.service');
exports.createArticle = async (req, res, next) => {
saveArticle(req.user._id, req.body.article)
.then((savedArticle) => {
if (savedArticle) {
return res.status(200).json({ article: savedArticle });
}
})
.catch(next);
};
[文件:article.controller.test.js]
const { createArticle } = require("../../../controllers/article.controller");
var { saveArticle } = require("../../../services/article.service");
const articleServiceHelper = require("../../../services/article.service");
const mockRequest = () => {
return {
title: "Sample article title",
description: "Sample article description",
body: "Sample article body"
};
};
const mockResponse = () => {
return {
status: jest.fn().mockReturnThis(),
json: jest.fn().mockReturnThis()
};
};
const mockNext = jest.fn();
const mockUser = {
_id: "6368ad4347dkhs"
}
const mockArticle = {
title: "Sample article title",
description: "Sample article description",
body: "Sample article body"
}
describe("Unit tests for article.controller.js file", () => {
describe("createArticle tests", () => {
test("If user can create an article", async () => {
//Arrange
let mockReq = mockArticle;
mockReq = { ...mockReq, _id: "6368ad4347dkhs" };
const mockRes = mockResponse();
const saveArticleSpy = jest.spyOn(articleServiceHelper, "saveArticle").mockResolvedValue({ article: mockArticle });
//Act
await createArticle(mockReq, mockRes, mockNext);
//Assert
expect(saveArticleSpy).toHaveBeenCalledTimes(1);
expect(saveArticleSpy).toHaveBeenCalledWith(mockUser._id, mockArticle);
expect(mockRes.status).toHaveBeenCalledWith(200);
expect(mockRes.json).toHaveBeenCalledWith({
article: mockArticle
});
expect(mockNext).toHaveBeenCalled();
});
});
});
[输出]
类型错误:无法读取未定义的属性(读取“_id”)
12 |
13 | exports.createArticle = async (req, res, next) => {
> 14 | saveArticle(req.user._id, req.body.article)
| ^
15 | .then((savedArticle) => {
16 | if (savedArticle) {
17 | return res.status(200).json({ article: savedArticle });
at Object.<anonymous>.exports.createArticle (controllers/article.controller.js:14:24)
at Object.<anonymous> (__tests__/unit/controllers/article.controller.test.js:41:13)
我想简单地测试 createArticle 函数。这是令人高兴和极端的情况。
您的代码有一些问题:
mockReq
不正确,应该是:const mockReq = { user: { _id: '6368ad4347dkhs' }, body: { article: mockArticle } }
在
./article.controller
之后应该需要jest.spyOn(articleServiceHelper, 'saveArticle')
模块,以便监视saveArticle()
函数。如果您在 ./article.controller
之前需要 jest.spyOn()
模块,则解构的 saveArticle()
函数是 not 被监视的。
根据断言,
articleServiceHelper.saveArticle()
的模拟解析值应该是mockArticle
而不是{ article: mockArticle }
。
createArticle()
函数应返回saveArticle()
返回的promise,以便您可以使用await createArticle()
。
所以完整的工作示例是:
article.service.js
:
exports.saveArticle = async (id, article) => {
throw new Error('Not implemented');
};
article.controller.js
:
const { saveArticle } = require('./article.service');
exports.createArticle = (req, res, next) => {
return saveArticle(req.user._id, req.body.article)
.then((savedArticle) => {
if (savedArticle) {
return res.status(200).json({ article: savedArticle });
}
})
.catch(next);
};
article.controller.test.js
:
const articleServiceHelper = require('./article.service');
const mockResponse = () => {
return {
status: jest.fn().mockReturnThis(),
json: jest.fn().mockReturnThis(),
};
};
const mockNext = jest.fn();
const mockUser = {
_id: '6368ad4347dkhs',
};
const mockArticle = {
title: 'Sample article title',
description: 'Sample article description',
body: 'Sample article body',
};
describe('Unit tests for article.controller.js file', () => {
describe('createArticle tests', () => {
test('If user can create an article', async () => {
//Arrange
const mockReq = { user: { _id: '6368ad4347dkhs' }, body: { article: mockArticle } };
const mockRes = mockResponse();
const saveArticleSpy = jest.spyOn(articleServiceHelper, 'saveArticle').mockResolvedValue(mockArticle);
const { createArticle } = require('./article.controller');
//Act
await createArticle(mockReq, mockRes, mockNext);
//Assert
expect(saveArticleSpy).toHaveBeenCalledTimes(1);
expect(saveArticleSpy).toHaveBeenCalledWith(mockUser._id, mockArticle);
expect(mockRes.status).toHaveBeenCalledWith(200);
expect(mockRes.json).toHaveBeenCalledWith({ article: mockArticle });
expect(mockNext).not.toHaveBeenCalled();
});
});
});
测试结果:
PASS stackoverflow/78011736/article.controller.test.js
Unit tests for article.controller.js file
createArticle tests
√ If user can create an article (33 ms)
-----------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------------|---------|----------|---------|---------|-------------------
All files | 85.71 | 50 | 66.66 | 85.71 |
article.controller.js | 100 | 50 | 100 | 100 | 6
article.service.js | 50 | 100 | 0 | 50 | 2
-----------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.12 s
Ran all test suites related to changed files.