Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to call Express Router directly from code with a "fake" request?

Tags:

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?

like image 398
oligofren Avatar asked Oct 12 '15 20:10

oligofren


People also ask

Is Express used for routing?

Express uses path-to-regexp for matching the route paths; see the path-to-regexp documentation for all the possibilities in defining route paths.

What is Express router used for?

The express. Router() function is used to create a new router object. This function is used when you want to create a new router object in your program to handle requests.

What is Express HTTP?

Express is a minimal and flexible Node. js web application framework that provides a robust set of features for web and mobile applications. In this article you'll learn how to create a http server using Express and other basics that you need to know about it.


2 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.

like image 181
carpenter Avatar answered Sep 20 '22 17:09

carpenter


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.

like image 32
oligofren Avatar answered Sep 23 '22 17:09

oligofren