开玩笑地测试多个测试文件端口3000已在使用中

时间:2019-01-29 14:05:30

标签: node.js express mongoose jestjs supertest

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

beforeEach(() =>  {

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

 });

我想在所有测试套件完成后终止玩笑。

6 个答案:

答案 0 :(得分:5)

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

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

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

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

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

现在,当您将应用程序提交为超级测试时,它将在端口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错误,并且可以继续并行运行测试。

答案 1 :(得分:1)

我遇到了这个问题,并且似乎通过设置开玩笑只使用一个工人来解决了这个问题。我认为此问题是由运行同一端口的多个服务器实例引起的,从而导致了冲突。

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

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

答案 2 :(得分:1)

我正在使用节点快递服务器4.16.2。如果您使用的是其他版本,则可能不适用于您。 关闭服务器时,在您的describe块中,输入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  

答案 3 :(得分:1)

最基本的操作是将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 :(得分:0)

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

答案 5 :(得分:0)

我遇到了同样的问题,原来最后一个测试用例在进入下一个测试套件之前不允许正确地关闭玩笑,所以我添加了

=TIME( 0, 0, A1 * 60 )