Node.js 如何在Express中模拟中间件以跳过单元测试的身份验证?

Node.js 如何在Express中模拟中间件以跳过单元测试的身份验证?,node.js,express,mocha.js,sinon,proxyquire,Node.js,Express,Mocha.js,Sinon,Proxyquire,我有下列特快专递 //index.js var service = require('./subscription.service'); var auth = require('../auth/auth.service'); var router = express.Router(); router.post('/sync', auth.isAuthenticated, service.synchronise); module.exports = router; 我想覆盖或模

我有下列特快专递

 //index.js

 var service = require('./subscription.service');
 var auth = require('../auth/auth.service');
 var router = express.Router();

 router.post('/sync', auth.isAuthenticated, service.synchronise);

 module.exports = router;
我想覆盖或模拟isAuthenticated以返回此

auth.isAuthenticated = function(req, res, next) { 
  return next(); 
}
下面是我的单元测试:

it('it should return a 200 response', function(done) {

  //proxyquire here?

  request(app).post('/subscriptions/sync')
  .set('Authorization','Bearer '+ authToken)
  .send({receipt: newSubscriptionReceipt })
  .expect(200,done);
});
我尝试过使用proxyquire模拟index.js-我想我需要存根路由器? 我还尝试在测试中覆盖

app.use('/subscriptions', require('./api/subscription'));

必须有一个简单的方法来模拟这一点,所以我不需要验证请求。有什么想法吗?

你可以使用
sinon
来存根
isAuthenticated
方法,但是你应该在
auth.isAuthenticated
的引用被设置为中间件之前,所以在你需要
index.js
app
之前先这样做。最有可能的情况是,您希望在每次挂起之前在
挂起:

var app;
var auth;

beforeEach(function() {
  auth = require('../wherever/auth/auth.service');
  sinon.stub(auth, 'isAuthenticated')
      .callsFake(function(req, res, next) {
          return next();
      });

  // after you can create app:
  app = require('../../wherever/index');
});

afterEach(function() {
  // restore original method
  auth.isAuthenticated.restore();
});

it('it should return a 200 response', function(done) {
  request(app).post('/subscriptions/sync')
  .set('Authorization','Bearer '+ authToken)
  .send({receipt: newSubscriptionReceipt })
  .expect(200,done);
});
请注意,即使在还原了
auth.isAuthenticated
之后,现有的
app
实例也将有存根作为中间件,因此如果出于某种原因需要获得原始行为,您需要创建另一个
app
实例


更新:有一种方法可以改变中间件的行为,而无需每次重新创建服务器,如中所述。

我遇到了类似的问题,感觉这个解决方案应该适合我,但我的解决方案仍然存在问题。对这个类似的问题有什么想法吗@卢凯斯兰根给出了答案there@SergeyLapin有没有办法使用Sinon模拟参数化中间件?中间件定义如:exports.authUser=function(options){return function(req,res,next){//基于options对象next()}}@hareshanat当然,我相信同样的方法,只需要返回中间件,而不是将其传递给callsFake:sinon.stub(authModule,'authUser').callsFake((选项)=>(req,res,next)=>{return next();})@谢尔盖:是的,明白了。非常感谢你!!