【问题标题】:NodeJS: Error found: listen EADDRINUSE :::3000?NodeJS:发现错误:监听 EADDRINUSE :::3000?
【发布时间】:2018-12-24 16:31:14
【问题描述】:

我目前面临一个无法解决的错误,并且我已经苦苦挣扎了几个小时。
我正在使用以下版本:
节点: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我有以下(这不是所有代码,而是bug的相关代码):

// 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 |

我尝试了几种方法来解决这个问题,将async await 添加到beforeEachafterEach 并尝试将sever.close 放入afterAllbeforeAll,但仍然遇到相同的错误。
然后,我尝试通过这样做来解决:
How Do I Shut Down My Express Server Gracefully When Its Process Is Killed?

但同样,没有运气。
最后,当我在 1 个文件中编写所有测试时,没有这个 error 就可以工作。有谁知道如何解决这个问题?我不想在 1 个文件中编写所有集成测试。
谢谢!

【问题讨论】:

  • 找到 this 似乎已经为我解决了!
  • 找到 this 为我修复了它!

标签: node.js express jestjs


【解决方案1】:

尝试设置 --runInBand 标志,这将按顺序运行您的测试。

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

在 package.json 脚本中:

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

[更新] 在进一步调查中,虽然您可以使用 --runInBand 顺序运行测试,但另一个选择是等待 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);
  });


});

【讨论】:

  • runInBand 有效,但有点像创可贴。 await server.close() 对我不起作用,查看上面的代码我想我遇到了同样的问题(codingwithmosh?)
  • 对两者都是:1) 这个例子来自“Coding with Mosh”和 2) 解决方案是使用“await server.close()”——否则会发生下一个测试运行在服务器实际关闭之前。谢谢@Nicholas Pretorius!
  • 你救了我的命,花了大约 3 个小时来解决它,是的,我也是“与 Mosh 合作”!!!
【解决方案2】:

我正在学习相同的课程并遇到相同的问题。 --runInBand 帮我解决了。

【讨论】:

  • 实际上,Mosh 在他的课程“5- 测试授权”的后面部分中介绍了这一点。他的解决方案是使用 await server.close();
【解决方案3】:

这里的问题是多次需要服务器文件。你不应该需要这样的服务器文件。每次执行此操作时,都会启动一个实例,在您的第一个测试文件中,一个服务器实例已经启动,而您的第二个文件需要服务器,它会尝试启动另一个实例,但是您的服务器已经在 3000 上运行,因此出现错误.

【讨论】:

  • 那么解决办法是什么?
  • 我推荐的解决方案是创建一个需要服务器和所有测试文件的基础文件,从那里,您的测试文件可以访问服务器对象并且服务器只需要一次。
  • 听起来不错,你有什么我看不到的参考吗?
  • 有趣的是,这被否决了——我认为这可能是最好的解决方案。我将尝试并实施它。你有没有想出答案 OrAssayag?
【解决方案4】:

我认为你的 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 | });

【讨论】:

  • 也可以直接改端口:const port = 3001;
  • 已经试过了,1次就ok了,然后返回监听EADDRINUSE :::3001
  • 在命令 { npm start } 之前使用 { sudo kill sudo lsof -t -i:3001 }。它将杀死 3001 上的进程。
  • 并尝试正确退出/杀死/结束您的应用程序。您的应用正在使用给定端口在后台运行。
  • 在我添加的 package.json 上但仍然无法正常工作:“scripts”:{“test”:“jest --verbose -t -i:3000”},
猜你喜欢
  • 2017-08-14
  • 2014-01-17
  • 2016-07-12
  • 2016-09-16
  • 2021-02-11
  • 2021-02-26
  • 2013-01-16
  • 1970-01-01
  • 2018-05-07
相关资源
最近更新 更多