web-dev-qa-db-ja.com

「偽の」リクエストを使用して、コードからExpress Routerを直接呼び出すことはできますか?

この質問 の接線、実際にHTTPを経由せずにExpressルーターをトリガーする方法があるかどうかを知りたいですか?

17
oligofren

ルーターには、要求、応答、およびコールバックを受け入れる "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 });
  });

Expressチームは、 SuperTest を使用して、 ルーター で統合テストを実行します。 SuperTestは引き続きネットワークを使用していると理解していますが、これらすべてを処理するため、テストがすべてメモリ内にあるかのように動作します。 SuperTestは広く使用されており、ルートをテストするための許容可能な方法のようです。

余談ですが、何をテストしようとしているのかは言いませんでしたが、いくつかのルートをテストすることが目標である場合、SuperTestの代わりに、Expressとは独立してテストできる別のモジュールにルートのロジックを抽出することもできます。

変化する:

routes
|
-- index.js

に:

routes
|
-- index.js
|
controllers
|
-- myCustomController.js

次に、テストは単にmyCustomController.jsをターゲットにして、必要な依存関係を注入することができます。

17
carpenter

そのためにrun-middlewareモジュールを使用できます。 Expressアプリを作成し、パラメーターを使用してアプリを呼び出すことができます

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()
    })
  });

より詳しい情報:

開示:私はこのモジュールのメンテナーであり、最初の開発者です。

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);
    });
}

しかし...欠点は、そもそも文書化されていない理由です。これは、Router.prototypeのプライベート関数です。

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

proto.handle = function handle(req, res, out) {
  var self = this;
  ...
}

したがって、このコードに依存することは、世界で最も安全なことではありません。

4
oligofren