Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Jest使用Express应用程序检测到打开的句柄_Javascript_Express_Jestjs - Fatal编程技术网

Javascript Jest使用Express应用程序检测到打开的句柄

Javascript Jest使用Express应用程序检测到打开的句柄,javascript,express,jestjs,Javascript,Express,Jestjs,我想弄清楚这件事已经有一段时间了,但是运气不好。我最初在使用MongoDB数据库执行简单的集成测试时遇到了这个问题,但我已经将代码剥离,并尽可能地简化了。我只运行了一个测试文件: // blah.test.js const express = require('express'); const app = express(); describe('test block', () => { let server = null; beforeEach(() => {

我想弄清楚这件事已经有一段时间了,但是运气不好。我最初在使用MongoDB数据库执行简单的集成测试时遇到了这个问题,但我已经将代码剥离,并尽可能地简化了。我只运行了一个测试文件:

// blah.test.js
const express = require('express');
const app = express();

describe('test block', () => {
    let server = null;

    beforeEach(() => {
        server = app.listen(3000, () => console.log('Listening on port 3000'));
    });

    afterEach(async () => {
        await server.close();
    });

    it('should pass the test', () => {
        expect(1).toBe(1);
    });
});
// blah2.test.js
const express = require('express');
const app = express();

describe('test block', () => {
    let server = null;

    beforeEach(() => {
        server = app.listen(3000, () => console.log('Listening on port 3000'));
    });

    afterEach(async () => {
        await server.close();
    });

    it('should pass the test', () => {
        expect(2).toBe(2);
    });
});
测试通过,但Jest通知我有一个打开的句柄,可以阻止它退出:

在这种情况下,它确实退出了,但仍然注意到一个打开的手柄。我想知道如何在不强行退出的情况下安全关闭这个。在以前的测试中,我会得到相同的openhandle警告,但也会出现一个错误,说明Jest在完成测试后一秒钟内没有退出

我还尝试使用
beforeAll()
aftereall()
,而不是
beforeach()
afterEach()
,但仍然遇到同样的问题。我知道测试在这种情况下不需要服务器,但我试图使它尽可能简单,试图找到打开和关闭服务器的问题

更新:我注意到,在添加第二个测试文件后,它似乎工作正常:

// blah.test.js
const express = require('express');
const app = express();

describe('test block', () => {
    let server = null;

    beforeEach(() => {
        server = app.listen(3000, () => console.log('Listening on port 3000'));
    });

    afterEach(async () => {
        await server.close();
    });

    it('should pass the test', () => {
        expect(1).toBe(1);
    });
});
// blah2.test.js
const express = require('express');
const app = express();

describe('test block', () => {
    let server = null;

    beforeEach(() => {
        server = app.listen(3000, () => console.log('Listening on port 3000'));
    });

    afterEach(async () => {
        await server.close();
    });

    it('should pass the test', () => {
        expect(2).toBe(2);
    });
});

如果有人能分享关于为什么会发生这种情况的任何想法,我们将不胜感激

我正在使用:

快递:4.16.3

笑话:23.5.0

NPM:6.3.0试试这个:

beforeAll(异步()=>{
//让我们创建一个服务器来接收集成调用
app=express();
app.get('/',(req,res)=>res.send('helloworld!'));
等待新的承诺((决心)=>{
应用程序监听(6666,()=>{
log('示例应用程序监听端口6666!');
返回resolve();
});
});
});
毕竟(()=>{console.log('closing…');app.close();});

我也有同样的问题,我昨天就解决了。问题在于调用app.listen()。您应该避免在app.js文件或jest测试文件中调用app.listen。只需从app.js导出带有路由的应用程序。然后,您可以使用supertest在测试中发出请求

// in your app.js
const app = express();
// add routes and middleware
module.exports = app;

// in your test file
import app from './app.js';
import supertest from 'supertest';

describe('test block', () => {
  it('test route', async (done) => {
    const res = await supertest(app).get('/').expect(200);
    done();
  });
});

因此,我通过将所有应用程序逻辑抽象到一个
app.js
文件来解决这个问题:

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

app.use('/api', routes);

module.exports = app
然后使用我的所有服务器逻辑创建一个
server.js
文件:

const app = require('./app.js')
const PORT = process.env.PORT || 3000
app.listen(PORT, () => console.log(`Listening on port: ${PORT}`))
然后将
app.js
导入测试文件,如下所示:

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

工作起来很有魅力

我看到了完全相同的行为。很高兴知道这里发生了什么。无论如何,
server.close
不会返回一个
承诺
。它返回
void
并使用回调。