Несколько попыток создания экземпляра сервера при запуске jest

#node.js #mongodb #jestjs #supertest

#node.js #mongodb #jestjs #супертест

Вопрос:

Хорошо, итак, я писал тесты для своего node.js приложение, использующее jest и supertest, для каждого набора тестов после первого, я получаю сообщение об ошибке Error: listen EADDRINUSE: address already in use :::3000 , я полагаю, это потому, что оно пытается запустить сервер для каждого тестового файла (у меня есть несколько тестовых файлов *.test.js в /tests )

Верхняя часть перед описанием тестов в каждом тестовом файле выглядит примерно так

 const request = require("supertest");
const app = require("../index.js"); // the express server

jest.setTimeout(30000);

let token;

beforeAll(done => {
  request(app)
    .post("/api/users/login")
    .send({
      email: "email here",
      password: "password here"
    })
    .end((err, response) => {
      token = response.body.data; // save the token!
      done();
    });
});

afterAll(done => {
  //logout() //Not implemented yet
  done();
});

/* Test starts here */
  

Итак, мне нужно знать, как предотвратить попытки jest инициализировать несколько экземпляров моего сервера? можно ли сказать, что весь этот код выполняется в файле предварительного тестирования или около того? могу ли я что-нибудь добавить в свой afterAll , чтобы заставить его остановить сервер, чтобы при запуске другого теста все было в порядке? Большое спасибо.

Ответ №1:

проблема здесь

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

Каждый раз, когда вы пытаетесь запросить, index.js вы технически копируете вставку всего кода изнутри index.js в свой тестовый скрипт.

Поскольку вы запускаете несколько тестовых файлов одновременно, каждый тест пытается запустить один и тот же код внутри index.js

Вы можете прочитать больше об этом http://fredkschott.com/post/2014/06/require-and-the-module-system /

Комментарии:

1. Спасибо, я знал, что это ошибка, поэтому у меня было 2 возможных решения: либо завершить все, что запускалось с index.js после каждого теста в afterAll или при наличии отдельного файла, который запускает предварительное тестирование, чтобы сервер запускался только один раз, есть идеи, как я мог бы пойти в любом случае?

2. Я думаю, вам нужно отделить основной сервер от ваших тестов, вы можете использовать одновременно Первый аргумент, который вы предоставляете одновременно, — это npm run start для запуска вашего сервера, а второй аргумент — npm run test например, для запуска всех ваших тестов… Это выглядело бы так "concurrently "npm run start" "npm run test1" "npm run test2" "

Ответ №2:

Отлично, поэтому, хотя удаление соединения при каждом запуске и одновременное использование в соответствии с ответом @ Omar Sherif было допустимым обходным решением, я счел это излишне сложным, настройка globalSetup в документации jest также была довольно ненужной проблемой.

Простое решение, которое я нашел, заключалось в следующем; поскольку запуск jest устанавливает NODE_ENV значение test, в моем index.js папка, вместо того, чтобы просто заставить мой сервер прослушивать сетевой порт, в чем не было необходимости, я добавил очень простое условие if.

 if (process.env.NODE_ENV !== "test") {
  app.listen(port, () => console.log(`Server Running on ${port}`));
}
  

Казалось, это помогло. Спасибо!