为什么即使我关闭了服务器,我的服务器已经 运行 在端口 4000 上

why am getting server is already running on port 4000 even i have closed the server

我正在 运行使用 Jest 库对我的节点项目进行单元测试,一切都运行良好。当我为路由身份验证创建新测试时,它开始显示服务器已经 运行ning 在端口 4000 上,即使我正在使用 afterEach() 函数关闭服务但不知道为什么我仍然得到服务器已经 运行在端口 4000 上宁。

即使我已经删除了路由身份验证的新测试并通过关闭所有终端重新启动我的项目但是每当我 运行 项目开始显示服务器已经 运行ning 在端口上的错误4000.

这是用户测试文件中正确关闭服务器的代码,在下一个测试文件中,我再次使用相同的函数进行服务器连接和关闭。

const request = require("supertest");
const { Genre } = require("../../models/genre");
const { User } = require("../../models/user");
const mongoose = require("mongoose");

let server;

describe("/api/genres", () => {
  beforeEach(() => {
    server = require("../../index");
  });
  afterEach(async () => {
    server.close();
    await Genre.remove({});
  });

第二个测试文件代码

const { User } = require("../../models/user");
const { Genre } = require("../../models/genre");
const request = require("supertest");
describe("auth middleware", () => {
  beforeEach(() => {
    server = require("../../index");
  });
  afterEach(async () => {
    await Genre.remove({});
    server.close();
  });

这是......................的输出 ● auth 中间件 › 应该 return 401 如果没有提供令牌

listen EADDRINUSE: address already in use :::4000

  10 | 
  11 | const port = process.env.PORT || 4000;
> 12 | const server = app.listen(port, () =>
     |                    ^
  at Function.listen (node_modules/express/lib/application.js:618:24)
  at Object.<anonymous> (index.js:12:20)
  at Object.<anonymous> (tests/integration/auth.test.js:6:14)

测试套件:1 个失败,3 个通过,总共 4 个 测试:1 次失败,26 次通过,总共 27 次 快照:共 0 个 时间:13.606s 运行 所有测试套件。

Index.js代码

const winston = require("winston");
const express = require("express");
const app = express();

require("./startup/logging")();
require("./startup/routes")(app);
require("./startup/db")();
require("./startup/config")();
require("./startup/validation")();

const port = process.env.PORT || 4000;
const server = app.listen(port, () =>
  winston.info(`Listening on port ${port}...`)
);
module.exports = server;

您的测试正在多次创建服务器 (index.js)。这使得服务器在许多情况下尝试侦听同一个端口。 Jest 文档显示,

If you have some work you need to do repeatedly for many tests, you can use beforeEach and afterEach.

很明显,您应该一次创建服务器,进行所有测试并关闭一次。方法是 beforeAllafterAll.

In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides beforeAll and afterAll to handle this situation.

所以,你的测试应该是这样的,

describe("auth middleware", () => {
  beforeAll(() => {
    server = require("../../index");
  });
  afterAll(async () => {
    await Genre.remove({});
    server.close();
  });

我不是Node.js方面的专家,但是你的bug的性质很简单;您正在尝试监听一个已经被监听的端口。

This post 提供了对 require() 的可靠描述,我相信这是您的麻烦的根源。

通过在每个测试用例程序中调用 require("../../index"),您可以有效地导出服务器 两次 ,这将导致两次 app.listen() 调用。

将服务器一次导出到某个主要测试程序会更好,这样您就可以通过在每个测试文件上调用 require() 来 运行 所有测试用例.这种方法在长 运行 中也好得多,因为添加额外的测试用例会容易 1000 倍;您可以编写一个新的测试脚本,将其导出到您的主测试程序,并将其附加到您的测试用例列表中。