【问题标题】:Server instances, jest and 'listen EADDRINUSE :::3000'服务器实例,开玩笑和“听 EADDRINUSE :::3000”
【发布时间】:2018-12-11 03:32:31
【问题描述】:

我是 jest、node 和 express 的新手,并且在测试我的应用时遇到了问题。

实际代码似乎可以正常工作 - 只是在将服务器实例传递给每个测试文件(user.test.js 和genres.test.js)并运行 jest 时,端口被阻塞。我认为这是因为我在每个测试文件中创建了服务器的重复实例,而没有意识到这一点。

使用标志 --runInBand 运行 jest 有效,仅使用一个测试文件也有效,但这并不能帮助我准确理解发生了什么。

我在下面发布了示例代码,但我正在努力减少它,但我确实认为大多数代码是无关紧要的,这取决于我如何将服务器传递给每个文件。

再次对篇幅表示歉意,但我认为这对除我以外的任何人来说都应该是非常基本的!谢谢。


index.js (.)

const express = require('express');
const app = express();
const genres = require('./routes/genres');
const users = require('./routes/users');
app.use(express.json());
app.use('/api/genres', genres);
app.use('/api/users', users);

const port = process.env.PORT || 3000;

const server = app.listen(port, () => console.log(`Listening on port ${port}...`));
console.log(typeof server);
// export server to be used in test file
module.exports = server;

genres.js (./routes)

const express = require('express');
const router = express.Router();

router.post('/', async (req, res) => {
    res.send('post genre ok');
});

module.exports = router;

users.js (./routes)

const express = require('express');
const router = express.Router();

router.post('/', async (req, res) => {
    res.send('post user ok');
});

module.exports = router;

genres.test.js (./tests)

const request = require('supertest');

let server;

describe('auth tests', () => {

    const exec = async function(){
        return await request(server)
            .post('/api/genres');
    };

    beforeEach(() => {
        server = require('../index');
    });
    afterEach(async () => {
        await server.close();
    });

    describe('POST /', () => {
        it('should return 200', async () => {
            const res = await request(server).post('/api/genres');
            expect(res.status).toBe(200);
        });
    });
});

user.test.js (./tests)

const request = require('supertest');

let server;

describe('user tests', () => {

    const exec = async function(){
        return await request(server)
            .post('/api/user');
    };

    beforeEach(() => {
        server = require('../index');
    });
    afterEach(async () => {
        await server.close();
    });

    describe('POST /', () => {
        it('should return 200', async () => {
            const res = await request(server).post('/api/users');
            expect(res.status).toBe(200);
        });
    });
});

【问题讨论】:

  • 该错误意味着该端口已在使用中,因为其他东西正在使用它,甚至可能是此代码的另一个副本。追踪重复的进程或切换到不同的端口。
  • 同意 - 我认为这绝对是这段代码,因为如果我删除其中一个测试文件,我将不再收到错误。这让我觉得这是我导出服务器实例的方式(即它正在被复制) - 但我没有足够的经验知道为什么

标签: node.js express jestjs


【解决方案1】:

希望this(第 2 点)能帮助其他人解决这个问题

通过将应用程序与服务器分离,它对我有用。我不确定这是否是正确的方法,也不是 100% 确定为什么它适用于应用程序而不是服务器,但我的所有测试现在都通过了。

index.js 现在是 app.js:

const express = require('express');
const app = express();
const genres = require('./routes/genres');
const users = require('./routes/users');
app.use(express.json());
app.use('/api/genres', genres);
app.use('/api/users', users);

// export server to be used in test file
module.exports = app;

服务器被分离到另一个文件中:

const app = require('./app');

const port = process.env.PORT || 3000;

app.listen(port, () => console.log(`Listening on port ${port}...`));

然后测试文件导入应用程序而不是服务器。因此每个测试都不会创建自己的实例。

注意:我认为 - 我真的不知道这有多正确,但如前所述,它有效

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 2019-01-08
    • 2019-11-06
    • 2018-12-24
    • 2023-03-12
    • 1970-01-01
    • 2014-09-18
    相关资源
    最近更新 更多