テスト用にExpressJSのインスタンスをプログラムでシャットダウンするにはどうすればよいですか?


106

Expressのインスタンスをシャットダウンする方法を理解しようとしています。基本的に、私はの逆が欲しい.listen(port)呼び出し -Expressサーバーにリスニングを停止させ、ポートを解放し、きれいにシャットダウンするにはどうすればよいですか?

これは奇妙なクエリのように思えるので、ここにコンテキストがあります。多分これにアプローチする別の方法があり、私はそれを間違った方法で考えています。私のsocket.io/nodejsアプリのテストフレームワークをセットアップしようとしています。これは単一ページのアプリなので、テストスクリプトでは( Mocha、しかしそれは重要ではありません)サーバーを起動し、テストを実行してサーバーをシャットダウンできるようにしたいと考えています。テストを開始する前にサーバーの電源がオンになっていると想定するか、テストの1つでサーバーを開始し、後続のすべてのテストでサーバーが稼働していると想定することで、これを回避できますが、それは本当に厄介です。各テストファイルで適切な設定でサーバーインスタンスを起動し、テストが終了したらそのインスタンスをシャットダウンすることをお勧めします。つまり、テストを実行するのに奇妙な依存関係はなく、すべてがクリーンです。また、起動/シャットダウンテストを実行できることも意味します。

これを行う方法についてのアドバイスはありますか?私はそれをダウンさせるために手動で例外をトリガーすることを考えましたが、それは面倒そうです。Expressのドキュメントとソースを調べましたが、サーバーをシャットダウンする方法を見つけることができません。このためのsocket.ioにも何かがあるかもしれませんが、ソケットサーバーはExpressサーバーに接続されているだけなので、これはExpressレイヤーで行う必要があると思います。

回答:


156

エクスプレスサーバーがノードのhttpサーバーから継承しなくなったため、状況は変わりました。さいわい、app.listenはサーバーインスタンスを返します。

var server = app.listen(3000);

// listen for an event
var handler = function() {
  server.close();
};

23
Mochaテストの場合は、require( 'app')を実行してappオブジェクトに拡張します。app.server = app.listen(3000); 後で言うことができます:var app = require( './ app'); app.server.close();
Jack Chi

2
サーバーをテストするときは、github.com /
visionmedia

server.close()これをフック内から呼び出す場合は、doneコールバックを渡すこともお勧めします。
ウラウリ

注:Express Applicationインスタンスである 'app'と、 'close'メソッドを持つ基底のネイティブHTTP Serverインスタンスである 'app.listen'の戻り値には大きな違いがあります。@JackChiはこれをほのめかした。
ajxs 2018

これは、開いたままになっている開いているクライアントソケットで問題を引き起こしませんか?
Cameron Tacklind

18

を使用しapp.close()ます。完全な例:

var app = require('express').createServer();
app.get('/', function(req, res){
  res.send('hello world');
});
app.get('/quit', function(req,res) {
  res.send('closing..');
  app.close();
});
app.listen(3000);

コール app.close()テストが終了したときにコールバックの内側。ただし、プロセスはまだ実行されていることを覚えておいてください(もうリッスンしていません)。

この後、プロセスを終了する必要がある場合は、を呼び出しますprocess.exit(0)

リンク:

app.close:http ://nodejs.org/docs/latest/api/http.html#server.close (同じことが当てはまります)

process.exit:http : //nodejs.org/docs/latest/api/process.html#process.exit


1
完璧、まさに私が探していたもの。コアノードのhttpサーバーを拡張していたため、Expressでは見つかりませんでした。完全に理解していませんでした。ありがとう!
drewww

スリジャンに感謝します。それは私にも役立ちました
アダムホプキンソン

これはまだ本当ですか?express.createServerは非推奨としてマークされ、アプリがhttp.jsのサーバーから継承しないことを示すエラーが発生します
Frank

4
これは急行3.以降は有効ではありません
gprasant

4
このようにサーバーを閉じるためのURLを公開することは、良い考えではありません。
shime 2017

2

私はさまざまな方法で「HTTPサーバーを終了する方法」のバリエーションに何度も答えました サポートチャネル。残念ながら、既存のライブラリーのいずれかが不足しているため、推奨できませんでした。それ以来、HTTPサーバーの正常な終了が予想されるすべてのケースを処理する(私は信じている)パッケージをまとめました。

https://github.com/gajus/http-terminator

http-terminatorの主な利点は次のとおりです。

  • それはサルパッチNode.js APIではありません
  • アタッチされたHTTPリクエストなしですべてのソケットを即座に破棄します
  • 進行中のHTTPリクエストでソケットに適切なタイムアウトを許可します
  • HTTPS接続を適切に処理します
  • keep-aliveを使用して接続に、接続を設定することでサーバーがシャットダウンしていることを通知します:ヘッダーを閉じる
  • Node.jsプロセスを終了しません

Express.jsでの使用:

import express from 'express';
import {
  createHttpTerminator,
} from 'http-terminator';

const app = express();

const server = app.listen();

const httpTerminator = createHttpTerminator({
  server,
});

await httpTerminator.terminate();


-1

サーバーを起動し、テストを実行し、サーバーを停止するbashスクリプトを記述することで、これを簡単に行うことができます。これには、スクリプトにエイリアスを設定して、すべてのテストをすばやく簡単に実行できるという利点があります。

このようなスクリプトを継続的な展開プロセス全体で使用しています。これについての洞察については、Jon RohanのDead Simple Gitワークフローご覧ください。


2
これは機能しますが、可能であればbashフリーのソリューションを使用します。多分それは愚かな設定ですが、サーバー構成固有のテスト+起動/シャットダウンテストを記述しやすくするため、テストコンテキストからサーバーを起動/停止したいと思います。さらに、サーバー関連のテストを別のスクリプトで実行する必要があるという間接的な影響もありません。
drewww 2011

なぜ環境固有のテストを書いているのですか?多分私は間違っているかもしれませんが、これは悪い習慣として私を襲います。開発環境に関係なく、テストがチーム全体で機能するように、テストに関係なく環境にとらわれないようにします。
Josh Smith、

ここでは環境固有のことは何もしていないと思います。サーバーにはいくつかの異なる起動オプション(ファイルからの構成オプションの読み取り、データストアからの状態の読み込みなど)があり、他のすべてをテストするのと同じフレームワークでテストすると便利です。また、たとえば、サーバーをシャットダウンして再度起動し、プロセスの状態を失わないことを確認するテストも必要です。bashでコードをテストするよりも、ノードからプログラムでそれを実行できる場合、それは簡単です。
drewww 2011

テストコードをbash自体に配置しないでください。コマンドラインで行うのと同じように、サーバーを起動してスクリプトからテストを実行するだけです。そこには本当の特別な魔法はありません。
Josh Smith、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.