web-dev-qa-db-ja.com

NodeJS:エラーが見つかりました:EADDRINUSE ::: 3000をリッスンしますか?


現在、解決できないバグに直面しており、数時間苦労しています。
次のバージョンを使用しています:
ノード:8.11.3
エクスプレス:4.16.3
ジェスト:22.2.2
マングース:5.2.3

私はjestを使用していくつかの統合テストを実行しようとしています。テストを含む2つのファイルがあります。
各ファイルに次のように書きました:

// Create the server before each test
beforeEach(() => {
    server = require('../../index');
});

// Close the server after each test
afterEach(async () => {
    if (server) {
        server.close();
    }
});

index.jsには、以下があります(これはすべてのコードではなく、バグに関連するコードです)。

// Listen to the server
const port = config.PORT || process.env.PORT || 3000;
module.exports = app.listen(port, () => {
   winston.info(`Listening to port ${port}...`);
});

npm testを実行すると、常にこの例外が発生します。

**listen EADDRINUSE :::3000**

  10 | // Listen to the server
  11 | const port = config.PORT || process.env.PORT || 3000;
> 12 | module.exports = app.listen(port, () => {
  13 |     winston.info(`Listening to port ${port}...`);
  14 | });
  15 |

beforeEachafterEachasync awaitを追加してこれを解決するいくつかの方法を試し、sever.closeをafterAllbeforeAllですが、同じエラーが発生します。

次に、私はこれを実行して解決しようとしました:
プロセスが終了したときにExpress Serverを正常にシャットダウンするにはどうすればよいですか?

しかし、再び、運がありません。
最後に、すべてのテストを1つのファイルに書き込んだ場合、これはerrorなしで機能します。誰かがこれを解決する方法を知っていますか?すべての統合テストを1つのファイルに記述したくありません。
ありがとうございます。

4
OrAssayag

--runInBandフラグを設定してみてください。これにより、テストが順次実行されます。

https://jestjs.io/docs/en/cli#runinband

Package.jsonスクリプト:

"scripts": {
    ...
    "test": "jest --watchAll --verbose --runInBand",
    ...
}

[更新]さらに調査すると、-runInBandを使用してテストを順次実行できますが、別のオプションは、promiseを返すため、server.close()を待つことです。そのため、あなたのafterEachで:

...
await server.close();
...

[UPDATE]この問題を解決するより良い方法は、index.jsファイルをindex.jsファイルとserver.jsファイルに分離することです。これにより、.listenなしでindex.jsファイルをテストに取り込むことができます。

// index.js
const express = require("express");
const app = express();

app.get("/", (req, res) => {
  res.status(200).send({ hello: "world!" });
});

module.exports = app;

次に、別のserver.jsファイルで:

const server = require("./index");

const PORT = process.env.PORT || 3001;

server.listen(PORT, () => {
  console.log(`App running on: ${PORT}`);
});

module.exports = server;

アプリを実行するとき、次を実行します:node server.js

これにより、index.jsファイルを次のようにテストにプルして、ルートをテストできます。

// test.js
const request = require("supertest");
const server = require("./index");

describe("GET /", () => {

  test("should return status 200", async () => {
    const res = await request(server).get("/");
    expect(res.status).toBe(200);
  });


});

8

私は同じコースをたどっており、同じ問題がありました。 --runInBand解決しました。

3
CriptoGirl

私はあなたのポート3000がどこかでビジーだと思います。または、多分このアプリはターミナルの他の場所で実行されています。チェックして、このアプリのすべてのインスタンスを閉じてください。

または

以下のコードを使用してみてください:

// Listen to the server
  11 | const port = config.PORT || process.env.PORT || 3001; // CHANGE POST 3000-> 3001
> 12 | module.exports = app.listen(port, () => {
  13 |     winston.info(`Listening to port ${port}...`);
  14 | });
0
Shubham Verma

ここでの問題は、サーバーファイルを複数回必要とすることです。このようなサーバーファイルは必要ありません。これを実行するたびにインスタンスが起動し、最初のテストファイルではサーバーのインスタンスが既に起動していますが、2番目のファイルにはサーバーが必要ですが、別のインスタンスを起動しようとしますが、サーバーはすでに3000で実行されているため、エラーが発生します。

0
Sachin S