Node.js 如何在mocha测试套件中的服务器上使用存根函数
在express serverNode.js 如何在mocha测试套件中的服务器上使用存根函数,node.js,express,unit-testing,server,mocha.js,Node.js,Express,Unit Testing,Server,Mocha.js,在express serverapp.js上测试endpoint/allowUser2时,我正在尝试存根auth.session /--auth.js-- module.exports.session=(请求、恢复、下一步)=>{ req.user=null; next(); }; /--app.js-- const express=require('express'); const auth=require('./auth'); 常量app=express(); 应用程序使用(授权会话);
app.js
上测试endpoint/allowUser2
时,我正在尝试存根auth.session
/--auth.js--
module.exports.session=(请求、恢复、下一步)=>{
req.user=null;
next();
};
/--app.js--
const express=require('express');
const auth=require('./auth');
常量app=express();
应用程序使用(授权会话);
app.get('/allowUser2',(请求,res)=>{
如果(!req.user)返回res.status(401.send();
if(req.user.user==2)返回res.status(200.send();
});
app.listen(4001).on('listening',()=>{
log(`HTTP服务器侦听端口4001`);
});
module.exports=app;
如果我的测试套件中只有一个测试文件test1.js
,auth
成功地被存根
/--test1.js--
让应用程序;
const sinon=要求(“sinon”);
const auth=require('../../auth.js');
const chai=要求(“chai”);
const chaiHttp=require('chai-http');
const{expect}=chai;
柴胡;柴胡;
让代理;
描述('应允许访问',()=>{
之前(异步()=>{
//删除require.cache[require.resolve('../../app.js')];//导致错误:侦听EADDRINUSE:地址已在使用中
sinon.stub(auth,'session').callsFake((req,res,next)=>{
req.user={user:1};
next();
});
app=require('../../app.js');
agent=chai.request.agent(应用程序);
});
之后(异步()=>{
auth.session.restore();
});
它('不允许访问',异步函数(){
const response=wait agent.get('/allowUser2');
期望(响应.状态).to.be.equal(200);
});
});
但是,如果我有多个需要app.js
的测试文件,那么我就有问题了。如果另一个测试文件(如下面的test2.js
)中已经需要app.js
,则当在test1.js
中再次需要时,节点不会重新加载app.js
。这会导致app.js
调用旧的auth.session
函数,而不是新的存根函数。因此,用户未经身份验证,测试失败
/--test2.js--
const chai=要求(“chai”);
const chaiHttp=require('chai-http');
const app=require('../../app.js');
const{expect}=chai;
柴胡;柴胡;
const-agent=chai.request.agent(应用程序);
描述('route/allowUser2',()=>{
它(“不允许访问”),异步函数(){
const response=wait agent.get('/allowUser2');
期望(响应.状态).to.be.equal(401);
});
});
我试图通过使用delete require.cache[require.resolve('../../app.js')]重新加载app.js
代码>。这在使用普通文件重新加载文件时有效,但当文件是类似于app.js
的服务器时,会导致错误:error:listen-EADDRINUSE:address-ready-in-use
重新创建:
下载
npm i
npm测试
如何在服务器上存根函数?更新:建议的解决方案
一个问题是您在app.js中使用直接方法引用的方式阻止了Sinon的工作
另一个问题(使用中的地址)是因为每次我们想要获取对应用程序的引用时,我们都试图在同一个端口中创建一个服务器。将应用程序/服务器的创建分解为单独的步骤可以缓解这个问题。一个解决方案是将app.js
转换为一个函数,在作为参数传入的端口号上启动服务器。然后在需要时随机更改端口。我不喜欢此选项,因为可能有某些原因需要将应用程序保留在特定端口上
app.js
const express=require('express');
const auth=require('./auth');
module.exports=(端口)=>{
常量app=express();
应用程序使用(授权会话);
app.get('/allowUser2',(请求,res)=>{
如果(!req.user)返回res.status(401.send();
if(req.user.user==2)返回res.status(200.send();
});
app.listen(端口).on('listening',()=>{
log(`HTTP服务器侦听端口${port}`);
});
返回应用程序;
};
需要时
app=require('../../app.js')((Math.random()*10000.toString().slice(0,4));
我没有在app.js
中导出app
,而是导出一个启动服务器并返回服务器实例和应用的函数。通过导出服务器实例,我可以关闭服务器。需要该应用程序才能进入chai。确保const app=express()
在此函数中,而不是在此函数之前,否则它不会重新创建
const express=require('express');
const auth=require('./auth');
常数端口=4000;
module.exports=()=>{
常量app=express();
应用程序使用(授权会话);
app.get('/allowUser2',(请求,res)=>{
如果(!req.user)返回res.status(401.send();
if(req.user.user==2)返回res.status(200.send();
});
app.post('/allowUser2',(请求、回复)=>{
如果(!req.user)返回res.status(401.send();
if(req.user.user==2)返回res.status(200.send();
});
返回{
服务器:app.listen(端口).on('listening',()=>{
log(`HTTP服务器侦听端口${port}`);
}),
应用程序,
};
};
然后在我的测试中,我可以在之前的中启动服务器,并在之后的中关闭服务器
let-app;
const sinon=要求(“sinon”);
const auth=require('../../auth.js');
const chai=要求(“chai”);
const chaiHttp=require('chai-http');
const{expect}=chai;
柴胡;柴胡;
让服务器;
描述('route/allowUser2',()=>{
之前(异步()=>{
//删除require.cache[require.resolve('../../app.js')];//导致错误:`error:listen-EADDRINUSE:address-ready-in-use`。
sinon.stub(auth,'session').callsFake((req,res,next)=>{
req.user={user:2};
next();
});
server=require('../../app.js')();
agent=chai.request.agent(server.a