【问题标题】:Jest testing multiple test file port 3000 already in use开玩笑测试多个测试文件端口 3000 已在使用中
【发布时间】:2023-04-01 17:54:01
【问题描述】:

我正在为我的 express 应用创建测试。该项目有多个测试文件。在每个模块中,服务器实例在 beforeEach() 方法中是必需的,并在 afterEach() 方法中关闭。但是在测试一两个模块之后,它会提高地址已经在使用中,并且 jest 不会终止。

beforeEach(() =>  {

    server = require('./../../../bin/www')});
afterEach(async() => { 
    server.close();
    /**
     * database cleanup logic goes here.
     */

 });

我希望 jest 在所有测试套件完成后终止。

【问题讨论】:

    标签: node.js express mongoose jestjs supertest


    【解决方案1】:
    server = require('./../../../bin/www')});
    afterEach(async() => { 
       await server.close();
    

    您只需等待正确关闭服务器。

    【讨论】:

      【解决方案2】:

      默认情况下仅并行运行测试套件。但是,运行测试的机器只有一个端口 3000(或端口 4000 等)

      这意味着如果你告诉你的应用监听一个端口,然后启动多个并发进程,就会发生端口冲突,Jest 会以EADDRINUSE - port already in use 退出。

      就像一些人已经提到的那样,您可以通过使用--runInBand 按顺序运行测试来解决问题。但是,您将失去并行化的性能优势。

      还有另一种方法...在运行测试时不要显式侦听端口。

      if (process.env.NODE_ENV !== 'test') {
        app.listen(port, () => console.log(`Listening on port ${port}`)
      }
      

      现在,当您将应用提供给 supertest 时,它将在端口 0 上运行您的应用,因为它尚未在端口上运行。

      const app = require('../app')
      const request = require('supertest')
      
      it('gets todos', async () => {
        const response = await request(app).get('/todos')
        expect(response.body.length).toEqual(3)
      }
      

      你问的端口 0 到底是什么?这就是你告诉 Unix 机器的方式......

      选择您找到的第一个随机可用的端口。

      现在每个测试套件都在一个随机可用的端口上运行,不再存在端口冲突的风险,这意味着我们已经解决了EADDRINUSE - port already in use 错误,我们可以继续并行运行测试。

      【讨论】:

      • 你如何让测试知道为他们的工人连接到哪个端口?例如,一旦服务器被绑定,我们如何知道它被绑定到了什么?
      • @fbartho,我实际上从来不需要知道哪个端口超级测试正在运行应用程序。在我上面的例子中,supertest 能够与应用程序通信,这就是我真正关心的。如果您真的需要知道哪个端口,您可以尝试挖掘 supertest 文档或查看它们的源代码。
      【解决方案3】:

      要做的最基本的事情是将您的 app.listen() 放在其他文件中,而不是包含所有路由的文件。 例如 : index.js

      const express = require("express");
      const app = express();
      const bodyParser = require("body-parser");
      
      app.use(bodyParser.json());
      
      const students = ["Elie", "Matt", "Joel", "Michael"];
      
      app.get("/", (req, res) => {
        return res.json(students);
      });
      
      module.exports = app;
      

      和 server.js

      const app = require("./index");
      
      app.listen(3000, () => console.log("server starting on port 3000!"));
      

      这样,Jest 根本不会阅读 app.listen() 。干杯!

      【讨论】:

      • 尝试了所有其他解决方案,但实际上没有用。这一个有效,即使对于生产来说似乎也是合理的。
      【解决方案4】:

      我遇到了同样的问题,结果是最后一个测试用例在移动到下一个测试套件之前不允许正确关闭,所以我添加了

      it('should blah blah', asyn(done) => {
         test code...
         done()
      })
      

      【讨论】:

        【解决方案5】:

        我正在使用节点快递服务器 4.16.2。如果您使用不同的版本,这可能不适用于您。 在您关闭服务器时的描述块中,await 为它。

        describe('auth midleware', () => {
                // loading the server
                beforeEach(() => {>         
                    server = require('../../../index')
                });
        
                // closing the server
                afterEach(async () => {
                    await server.close();        
                });
        
        
                // the tests will go here
            });
        

        在您完成此操作后,在命令行中运行您的节点应用程序。

        node index.js
        

        检查你的 package.json,你的脚本测试标签是如何命名的。我的是测试。

        { ...
              "scripts": {
                "test": "jest --verbose --coverage --forceExit --watchAll --maxWorkers=1"
              }
              ...
            }
        

        之后再次运行您的测试。

        npm test  
        

        【讨论】:

          【解决方案6】:

          还有一个选项 --runInBand 来逐个运行测试。

          【讨论】:

            【解决方案7】:

            我遇到了这个问题,似乎已经通过将 jest 设置为仅使用一名工作人员来解决它。我认为这个问题是由多个使用相同端口的服务器实例引起的,从而导致冲突。

            这是我的 npm package.json 文件中的行。 --maxWorkers=1 似乎成功了 (https://jestjs.io/docs/en/cli#maxworkers-num-string)。

            "scripts": {
              "test": "jest --forceExit --detectOpenHandles  --watchAll --maxWorkers=1"
            },
            

            【讨论】:

            • 如果同时使用 runInBand 和 maxWorkers 会导致此错误:Both --runInBand and --maxWorkers were specified, but these two options do not make sense together. Which is it?
            猜你喜欢
            • 2020-05-26
            • 1970-01-01
            • 2019-11-10
            • 2020-02-06
            • 2020-03-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-18
            相关资源
            最近更新 更多