【问题标题】:why am getting server is already running on port 4000 even i have closed the server为什么服务器已经在端口 4000 上运行,即使我已经关闭了服务器
【发布时间】:2020-03-04 03:14:48
【问题描述】:

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

即使我已经删除了路由身份验证的新测试,并通过关闭所有终端重新启动我的项目,但每当我运行项目时,它开始显示服务器已在端口 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 中间件 › 如果没有提供令牌,应该返回 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 文件中吗?
  • 多次调用app.listen会这样做。
  • 为什么不等待server.close();
  • @RobJohansen 我已经更新了 index.js 代码参见
  • @ManuelSpigolon 我试过了,但没有运气

标签: node.js express jestjs supertest


【解决方案1】:

您的测试正在多次创建服务器 (index.js)。这使得服务器在很多情况下都试图监听同一个端口。 Jest 文档中写道,

如果你有一些工作需要重复做很多测试,你 可以使用 beforeEach 和 afterEach。

很明显,您应该创建一次服务器,完成所有测试并关闭一次。用于此的方法是beforeAllafterAll

在某些情况下,您只需要设置一次,在开始时 文件。当设置为 异步的,所以你不能内联。 Jest 提供 beforeAll 和 毕竟要处理这种情况。

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

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

【讨论】:

  • 即使我将 beforeEach 和 afterEach 更改为 beforeAll 和 afterAll,问题仍然存在
  • 请发布你的 index.js
  • 请检查上面我已经编辑并添加了 index.js 文件
【解决方案2】:

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

This 帖子提供了对require() 的可靠描述,我认为这是您的麻烦的根源。

通过在您的每个测试用例程序中调用require("../../index"),您实际上是在两次导出服务器,这会导致两次app.listen() 调用。

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

【讨论】:

    猜你喜欢
    • 2016-07-30
    • 2020-07-26
    • 2019-03-07
    • 2013-02-10
    • 2016-03-11
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 2016-09-02
    相关资源
    最近更新 更多