// 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. Кто-нибудь знает, как это решить? Я не хочу записывать все свои интеграционные тесты в один файл ..
Спасибо!
Нашел это, который исправил это для меня!





Я думаю, что ваш порт 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 раз нормально, а затем вернитесь к прослушиванию EADDRINUSE ::: 3001
Используйте {sudo kill sudo lsof -t -i:3001} перед командой {npm start}. Это убьет процесс на 3001.
И попробуйте выйти / убить / завершить приложение должным образом. Ваше приложение работает в фоновом режиме с заданным портом.
В package.json я добавил, но все еще не работает: "scripts": {"test": "jest --verbose -t -i: 3000"},
попробуйте без скрипта, запустите команду на терминале перед использованием теста npm
Проблема здесь в том, что файл сервера требуется несколько раз. Вы не должны требовать такой файл сервера. Каждый раз, когда вы это делаете, экземпляр запускается, в вашем первом тестовом файле уже запущен экземпляр сервера, при этом требуется сервер для вашего второго файла, он пытается запустить другой экземпляр, но тогда ваш сервер уже работает на 3000 и, следовательно, ошибка .
Итак, какое решение?
Решение, которое я рекомендую, - создать базовый файл, для которого требуется сервер и все ваши тестовые файлы в нем, и оттуда ваши тестовые файлы могут получить доступ к объекту сервера, а сервер потребуется только один раз.
Звучит отлично, есть ли у вас какие-нибудь ссылки, которые я не могу увидеть?
Забавно, что это было отклонено - я думаю, что это может быть лучшим решением. Я собираюсь попробовать реализовать это. Вы когда-нибудь придумывали ответ OrAssayag?
Попробуйте установить флаг --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?)
Да для обоих: 1) Этот пример взят из «Кодирования с Mosh» и 2) Решение состоит в использовании «await server.close ()» - иначе произойдет следующее: следующий тест будет запущен до фактического закрытия сервера. Спасибо, @Nicholas Pretorius!
Вы спасли мне жизнь, потратили около 3 часов, чтобы решить эту проблему, да, я тоже "Кодирование с Мошем" !!!
Я следую тому же курсу, и у меня была такая же проблема. --runInBand решил это за меня.
Собственно, Мош освещает это в более позднем разделе своего курса «5 - Проверка авторизации». Его решение - использовать для ожидания server.close ();
Нашел это, который, кажется, решил эту проблему для меня!