Tangential to this question, I would like to find out if there is a way of triggering the Express Router without actually going through HTTP?
3 Answers
The Router has a "private" method named handle
that accepts a request, a response, and a callback. You can take a look at the tests that Express has for its Router. One example is:
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 });
});
The Express team uses SuperTest to perform integration tests on the Router. It is my understanding that SuperTest still uses the network but they handle all of this for you so it behaves as if the tests were all in memory. SuperTest does seem to be widely used and an acceptable way to test your routes.
As an aside, you didn't say what you were attempting to test but if your goal is to test some routes, an alternative to SuperTest could be to extract the logic in your routes into a separate module that can be tested independent of Express.
change:
routes
|
-- index.js
to:
routes
|
-- index.js
|
controllers
|
-- myCustomController.js
The tests could then simply target myCustomController.js
and inject any necessary dependencies.

- 1,192
- 1
- 14
- 25
-
1@oligofren: I have updated the answer to show how to send a fake request to the router. – carpenter Oct 14 '15 at 16:44
-
Haha, you even added a link to almost the same line as I did! – oligofren Oct 14 '15 at 17:39
-
3Just if someone needs to use this on a controller, you can handle the re-routing request changing the URL (req.url="/whatever") and using: req.app._router.handle(req,res,next); – Pablo Romeu Apr 10 '18 at 06:54
By going to the source of Express, I was able to find out that there is indeed an API that is just as simple as I wished for. It is documented in 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);
});
}
But ... the downside is, exactly the reason why it is undocumented in the first place: it is a private function of Router.prototype:
/**
* Dispatch a req, res into the router.
* @private
*/
proto.handle = function handle(req, res, out) {
var self = this;
...
}
So relying on this code is not the safest thing in the world.

- 20,744
- 16
- 93
- 180
-
1Looks like we found the same thing. Wish there was something that wasn't a private method. – carpenter Oct 14 '15 at 17:28
-
I was probably busy adding the info I found while you edited yours :-) I'll go with the private method as that approach simplifies a lot. Just adding a bunch of tests in case an upgrade of Express should break the interface. – oligofren Oct 14 '15 at 17:37
You can use run-middleware
module exactly for that. You create an express app a usuaul, and then you can call the app using your parameters
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()
})
});
More info:
- Module page in Github & NPM;
- Examples of use run-middleware module
Disclosure: I am the maintainer & first developer of this module.

- 23,232
- 12
- 77
- 117
-
How do you send a request body in a POST, PUT, or PATCH request with this? – idbehold Sep 14 '16 at 15:15
-
Good question. by passing an options parameter. (e.g. `app.runMiddleware('/path',{method:'post'}, callback)`. – Aminadav Glickshtein Sep 14 '16 at 18:13
-
-
It is possible. Did you see the module page in GitHub? there is an example for that. If you don't found it I will answer here – Aminadav Glickshtein Sep 15 '16 at 04:03
-
I've looked [here](https://github.com/AminaG/node-run-middleware/blob/master/example.js) but didn't find any examples of a POST request body being set. – idbehold Sep 15 '16 at 04:08
-
`app.runMiddleware('/route',{method:'post',body:'The body can be string/buffer or JSON'},callback)` – Aminadav Glickshtein Sep 15 '16 at 04:22