如何在node.js应用程序中对控制器进行单元测试?
我正在为node.js应用程序使用fastify框架,并将sequelize作为ORM。我使用mocha、chai和Sinon进行单元测试。我必须对我的控制器功能进行单元测试。以下是控制器函数示例如何在node.js应用程序中对控制器进行单元测试?,node.js,unit-testing,controller,mocha.js,chai,Node.js,Unit Testing,Controller,Mocha.js,Chai,我正在为node.js应用程序使用fastify框架,并将sequelize作为ORM。我使用mocha、chai和Sinon进行单元测试。我必须对我的控制器功能进行单元测试。以下是控制器函数示例 // controllers.js; const service = require('../services'); exports.create = (req, reply) => { const attributes = req.body; service.create(attr
// controllers.js;
const service = require('../services');
exports.create = (req, reply) => {
const attributes = req.body;
service.create(attributes)
.then((result) => {
reply.code(201).send(result);
})
.catch((error) => {
reply.send(error);
});
};
我的服务文件如下:
// services.js;
const { Model } = require('../models');
function create(attributes) {
return Model.create(attributes);
}
module.exports = { create };
在上面的代码中,我只想对controllers.js中的“create”函数进行单元测试。问题是,它不应该调用数据库,因为它是单元测试。但是service.js中的Model.create文件将调用数据库。如何仅对控制器进行单元测试?您应该存根
服务。创建方法并创建模拟req
,回复对象
例如
controller.js
:
const service=require('./service');
exports.create=(请求、回复)=>{
const attributes=req.body;
服务
.创建(属性)
。然后((结果)=>{
回复。代码(201)。发送(结果);
})
.catch((错误)=>{
回复。发送(错误);
});
};
service.js
:
const{Model}=require('./models');
函数创建(属性){
返回模型。创建(属性);
}
module.exports={create};
models.js
:
const模型={
创建(){
log('real implementation');
},
};
module.exports={Model};
controller.test.js
:
const controller=require('./controller');
常量服务=需要('./服务');
const sinon=要求(“sinon”);
const flushPromises=()=>新承诺(setImmediate);
描述('6253621',()=>{
之后(()=>{
sinon.restore();
});
它('should create',async()=>{
const mResult=‘success’;
sinon.stub(服务,'create').resolves(mResult);
const mReq={body:{};
const mReply={code:sinon.stub().returnsThis(),send:sinon.stub()};
controller.create(mReq、mReply);
等待flushPromises();
sinon.assert.calledWith(mReply.code,201);
sinon.assert.calledWith(mReply.send,'success');
});
它('应该处理错误',异步()=>{
const mError=新错误(“网络”);
sinon.存根(服务,“创建”)。拒绝(MEROR);
const mReq={body:{};
const mReply={code:sinon.stub().returnsThis(),send:sinon.stub()};
controller.create(mReq、mReply);
等待flushPromises();
sinon.assert.calledWith(mReply.send,mError);
});
});
单元测试结果和覆盖率报告:
6253621
✓ 应该创造
✓ 应该处理错误
2次通过(13毫秒)
---------------|---------|----------|---------|---------|-------------------
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s
---------------|---------|----------|---------|---------|-------------------
所有文件| 83.33 | 100 | 60 | 83.33 |
controller.js | 100 | 100 | 100 | 100 |
models.js | 66.67 | 100 | 0 | 66.67 | 3
service.js | 66.67 | 100 | 0 | 66.67 | 4
---------------|---------|----------|---------|---------|-------------------
谢谢@slideshowp2。它工作了,但有一件事是它需要数据库URL。我想因为我需要服务文件中的模型,所以它需要数据库URL。如何在服务中存根或模拟此模型。?它将错误显示为TypeError[ERR_INVALID_ARG_TYPE]:“url”参数必须是string类型。只有在终端导出数据库\u URL中输入以下内容后,测试才能成功运行=postgres://username:password@localhost:5432/databasename。那么这可以看作是单元测试吗?