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 |

Я попробовал несколько способов решить эту проблему, добавив async await в beforeEach и для afterEach, а также попытался поместить sever.close в afterAll и beforeAll, но все равно получил ту же ошибку. Затем я попытался решить, выполнив следующее:
Как мне корректно завершить работу сервера Express, когда его процесс остановлен?

Но опять же безуспешно. Наконец, когда я записал все тесты в один файл, он работает и без этого error. Кто-нибудь знает, как это решить? Я не хочу записывать все свои интеграционные тесты в один файл ..
Спасибо!

Нашел это, который, кажется, решил эту проблему для меня!

Simon van der Weele 29.04.2020 08:49

Нашел это, который исправил это для меня!

Simon van der Weele 29.04.2020 08:52
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
2
11 090
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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;

Shubham Verma 17.07.2018 07:29

Уже пробовал это сделать, работает 1 раз нормально, а затем вернитесь к прослушиванию EADDRINUSE ::: 3001

Or Assayag 17.07.2018 07:45

Используйте {sudo kill sudo lsof -t -i:3001} перед командой {npm start}. Это убьет процесс на 3001.

Shubham Verma 17.07.2018 07:51

И попробуйте выйти / убить / завершить приложение должным образом. Ваше приложение работает в фоновом режиме с заданным портом.

Shubham Verma 17.07.2018 07:52

В package.json я добавил, но все еще не работает: "scripts": {"test": "jest --verbose -t -i: 3000"},

Or Assayag 17.07.2018 08:02

попробуйте без скрипта, запустите команду на терминале перед использованием теста npm

Shubham Verma 17.07.2018 08:16

Проблема здесь в том, что файл сервера требуется несколько раз. Вы не должны требовать такой файл сервера. Каждый раз, когда вы это делаете, экземпляр запускается, в вашем первом тестовом файле уже запущен экземпляр сервера, при этом требуется сервер для вашего второго файла, он пытается запустить другой экземпляр, но тогда ваш сервер уже работает на 3000 и, следовательно, ошибка .

Итак, какое решение?

Or Assayag 18.07.2018 06:37

Решение, которое я рекомендую, - создать базовый файл, для которого требуется сервер и все ваши тестовые файлы в нем, и оттуда ваши тестовые файлы могут получить доступ к объекту сервера, а сервер потребуется только один раз.

Sachin S 18.07.2018 06:42

Звучит отлично, есть ли у вас какие-нибудь ссылки, которые я не могу увидеть?

Or Assayag 18.07.2018 08:58

Забавно, что это было отклонено - я думаю, что это может быть лучшим решением. Я собираюсь попробовать реализовать это. Вы когда-нибудь придумывали ответ OrAssayag?

NickW 10.12.2018 19:29
Ответ принят как подходящий

Попробуйте установить флаг --runInBand, это запустит ваши тесты последовательно.

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

В скриптах package.json:

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

[ОБНОВЛЕНИЕ] При дальнейшем исследовании, хотя вы можете использовать --runInBand для последовательного запуска тестов, другой вариант - дождаться server.close (), поскольку он возвращает обещание. Таким образом, в вашем afterEach:

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

[ОБНОВИТЬ] Я считаю, что лучший способ решить эту проблему - разделить файл index.js на файл index.js и файл server.js. Это позволяет вам добавить файл index.js в тесты без .listen:

// 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.info(`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?)

NickW 10.12.2018 19:29

Да для обоих: 1) Этот пример взят из «Кодирования с Mosh» и 2) Решение состоит в использовании «await server.close ()» - иначе произойдет следующее: следующий тест будет запущен до фактического закрытия сервера. Спасибо, @Nicholas Pretorius!

Jérémie 15.12.2018 05:17

Вы спасли мне жизнь, потратили около 3 часов, чтобы решить эту проблему, да, я тоже "Кодирование с Мошем" !!!

Vladislav Guleaev 16.02.2019 23:16

Я следую тому же курсу, и у меня была такая же проблема. --runInBand решил это за меня.

Собственно, Мош освещает это в более позднем разделе своего курса «5 - Проверка авторизации». Его решение - использовать для ожидания server.close ();

CriptoGirl 07.03.2019 19:01

Другие вопросы по теме