是否可以通过“假”请求直接从代码中调用 Express Router?
Posted
技术标签:
【中文标题】是否可以通过“假”请求直接从代码中调用 Express Router?【英文标题】:Is it possible to call Express Router directly from code with a "fake" request? 【发布时间】:2016-01-10 11:04:32 【问题描述】:与this question 相切,我想知道是否有一种方法可以在不通过 HTTP 的情况下触发 Express Router?
【问题讨论】:
【参考方案1】:路由器有一个"private" method named handle
,它接受请求、响应和回调。您可以查看 Express 对其Router 的测试。一个例子是:
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 );
);
Express 团队使用SuperTest 对Router 执行集成测试。据我了解,SuperTest 仍然使用网络,但它们会为您处理所有这些,因此它的行为就像测试都在内存中一样。 SuperTest 似乎被广泛使用并且是一种可接受的测试路线的方法。
顺便说一句,您没有说您要测试什么,但如果您的目标是测试某些路由,SuperTest 的替代方法可能是将您的路由中的逻辑提取到一个单独的模块中,该模块可以独立测试快递。
改变:
routes
|
-- index.js
到:
routes
|
-- index.js
|
controllers
|
-- myCustomController.js
然后测试可以简单地以myCustomController.js
为目标并注入任何必要的依赖项。
【讨论】:
@oligofren:我已经更新了答案以显示如何向路由器发送虚假请求。 哈哈,你甚至添加了一个链接到几乎与我相同的行! 如果有人需要在控制器上使用它,您可以处理更改 URL (req.url="/whatever") 的重新路由请求并使用:req.app._router.handle (req,res,next); 你是最棒的谢谢【参考方案2】:通过查看 Express 的源代码,我发现确实有一个 API 与我希望的一样简单。它记录在the tests for 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);
);
但是......缺点是,它最初没有被记录的原因是:它是 Router.prototype 的私有函数:
/**
* Dispatch a req, res into the router.
* @private
*/
proto.handle = function handle(req, res, out)
var self = this;
...
所以依赖这段代码并不是世界上最安全的事情。
【讨论】:
看起来我们找到了同样的东西。希望有一些不是私有方法的东西。 我可能正忙着添加我在您编辑您的信息时找到的信息 :-) 我将使用私有方法,因为这种方法可以简化很多。只需添加一堆测试,以防 Express 升级会破坏界面。【参考方案3】:您完全可以使用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()
)
);
更多信息:
模块页面在Github & NPM; Examples of use run-middleware module披露:我是这个模块的维护者和第一个开发者。
【讨论】:
如何在 POST、PUT 或 PATCH 请求中发送请求正文? 好问题。通过传递选项参数。 (例如app.runMiddleware('/path',method:'post', callback)
.
是的,但是如何设置实际的请求正文?
有可能。你在 GitHub 上看到模块页面了吗?有一个例子。如果你没有找到它,我会在这里回答
我查看了here,但没有找到任何设置 POST 请求正文的示例。以上是关于是否可以通过“假”请求直接从代码中调用 Express Router?的主要内容,如果未能解决你的问题,请参考以下文章
是否有任何应用程序从Google日历活动创建(假)传入短信?
是否可以直接从 html img 标签 src 向服务器请求文件并使用 jwt 身份验证标头加载它?