I've been trying to figure this out for a while now, but with no luck. I initially had the issue when performing simple integration tests with a MongoDB database, but I've stripped the code right down and made it as simple as I can. The only thing I have running is a single test file:
// 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);
});
});
The test passes, but Jest informs me of an open handle which could prevent it from exiting:
On this occasion, it did exit, but still notices an open handle. I would like to know how to safely close this, without forcing exit. With previous tests, I would get the same open handle warning, but also with an error stating that Jest didn't exit one second after completing the tests.
I also tried using beforeAll()
and afterAll()
, instead of beforeEach()
and afterEach()
, but still get the same problem. I know the test doesn't require the server on this occasion, but I was trying to make it as simple as possible to try to find the issue with opening and closing the server.
UPDATE: I noticed that it seems to work fine as soon as I add a second test file:
// 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);
});
});
No open handles with two tests running
If anyone can share any ideas as to why this happens, it would be much appreciated.
I am using:
Express: 4.16.3
Jest: 23.5.0
NPM: 6.3.0
答案 0 :(得分:6)
因此,我通过将所有应用程序逻辑抽象到一个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')
像魅力一样工作!
答案 1 :(得分:0)
尝试一下:
beforeAll(async () => {
// let's create a server to receive integration calls
app = express();
app.get('/', (req, res) => res.send('Hello World!'));
await new Promise((resolve) => {
app.listen(6666, () => {
console.log('Example app listening on port 6666!');
return resolve();
});
});
});
afterAll(() => { console.log('closing...'); app.close(); });
答案 2 :(得分:0)
我遇到了同样的问题,昨天我能够解决它。问题是调用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();
});
});