是否可以通过"假"请求直接从代码中调用Express Router?

oli*_*ren 17 routing node.js express run-middleware

这个问题相关,我想知道是否有一种方法可以在没有实际通过HTTP的情况下触发Express Router?

car*_*ter 17

路由器有一个名为"private"的方法handle,它接受请求,响应和回调.您可以查看Express对其路由器的测试.一个例子是:

it('should support .use of other routers', function(done){
    var router = new Router();
    var another = new Router();

    another.get('/bar', function(req, res){
      res.end();
    });
    router.use('/foo', another);

    router.handle({ url: '/foo/bar', method: 'GET' }, { end: done });
  });
Run Code Online (Sandbox Code Playgroud)

Express团队使用SuperTest路由器上执行集成测试.我的理解是,SuperTest仍然使用网络,但它们会为您处理所有这些,因此它的行为就像测试都在内存中一样.SuperTest似乎被广泛使用,是测试路线的可接受方式.

顺便说一下,你没有说你试图测试的是什么,但是如果你的目标是测试一些路线,SuperTest的替代方法可能是将路由中的逻辑提取到一个独立的模块中,该模块可以独立于Express进行测试.

更改:

routes
|
-- index.js
Run Code Online (Sandbox Code Playgroud)

至:

routes
|
-- index.js
|
controllers
|
-- myCustomController.js
Run Code Online (Sandbox Code Playgroud)

然后,测试可以简单地定位myCustomController.js并注入任何必要的依赖项.

  • 就算有人需要在控制器上使用它,也可以通过更改URL(req.url =“ / whatever”)并使用以下方法来处理重新路由请求:req.app._router.handle(req,res,next); (2认同)

oli*_*ren 5

通过访问 Express 的源代码,我能够发现确实有一个和我希望的一样简单的 API。它记录在express.Router 的测试中

/** 
* @param {express.Router} router 
*/
function dispatchToRouter(router, url, callback) {

    var request = {
        url  : url,
        method : 'GET'
    };

    // stub a Response object with a (relevant) subset of the needed
    // methods, such as .json(), .status(), .send(), .end(), ...
    var response = {
        json : function(results) {
            callback(results);
        }
    };

    router.handle(request, response, function(err) {
        console.log('These errors happened during processing: ', err);
    });
}
Run Code Online (Sandbox Code Playgroud)

但是......缺点是,它最初没有被记录的原因正是:它是 Router.prototype 的私有函数:

/**
 * Dispatch a req, res into the router.
 * @private
 */

proto.handle = function handle(req, res, out) {
  var self = this;
  ...
}
Run Code Online (Sandbox Code Playgroud)

所以依赖这个代码并不是世界上最安全的事情。


Ami*_*ein 5

您可以run-middleware为此使用模块。您创建了一个快递应用程序,然后可以使用您的参数调用该应用程序

it('should support .use of other routers', function(done){
    var app=require('express')()      
    app.get('/bar', function(req, res){
      res.status(200).end();
    });
    app.runMiddleware('/bar',{options},function(responseCode,body,headers){
        console.log(responseCode) // Should return 200
        done()
    })
  });
Run Code Online (Sandbox Code Playgroud)

更多信息:

披露:我是该模块的维护者和第一开发者。