如何修复错误Jest检测到以下3个打开的句柄可能会阻止Jest退出

amrnrhlw  于 2023-04-10  发布在  Jest
关注(0)|答案(4)|浏览(248)

刚刚开始使用jest测试一些节点应用程序。express-generator用于搭建。
在第一次测试中,我得到以下错误:
Jest检测到以下3个打开的句柄可能会阻止Jest退出
复制步骤:

git clone git@github.com:gandra/node-jest-err-demo.git   
cd node-jest-err-demo       
npm install   
cp .env.example .env    
npm run test

npx envinfo --preset jest输出:

npx: installed 1 in 1.896s

  System:
    OS: macOS High Sierra 10.13.4
    CPU: x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz   Binaries:
    Node: 9.3.0 - /usr/local/bin/node
    Yarn: 1.5.1 - /usr/local/bin/yarn
    npm: 5.7.1 - /usr/local/bin/npm   npmPackages:
    jest: ^23.1.0 => 23.1.0

知道怎么修吗
以下是github上的相关问题:https://github.com/facebook/jest/issues/6446

khbbv19g

khbbv19g1#

detectOpenHandles选项用于检测打开的句柄,应该正常使用。错误警告 * 潜在 * 打开的句柄:
Jest检测到以下4个打开的句柄可能会阻止Jest退出
即使手柄关闭,错误仍然会出现。
此应用程序的实际问题是数据库连接没有真正关闭:

if (process.env.NODE_ENV === 'test') {
  mongoose.connection.close(function () {
    console.log('Mongoose connection disconnected');
  });
}

由于某种原因,NODE_ENVdev,尽管文档中指出它应该是test
在应用程序启动时立即关闭数据库连接可能会导致实际使用数据库连接的单元出现问题。如指南中所述,MongoDB连接应在测试结束时进行。由于使用默认Mongoose连接,因此它可以是:

afterAll(() => mongoose.disconnect());
ykejflvf

ykejflvf2#

我是这样解决这个问题的。

afterAll(async () => {
  await new Promise(resolve => setTimeout(() => resolve(), 10000)); // avoid jest open handle error
});

然后在给出问题的特定测试中设置jest.setTimeout。

describe('POST /customers', () => {
  jest.setTimeout(30000);
  test('It creates a customer', async () => {
    const r = Math.random()
      .toString(36)
      .substring(7);
    const response = await request(server)
      .post('/customers')
      .query({
        name: r,
        email: `${r}@${r}.com`,
        password: 'beautiful',
      });
    // console.log(response.body);
    expect(response.body).toHaveProperty('customer');
    expect(response.body).toHaveProperty('accessToken');
    expect(response.statusCode).toBe(200);
  });
});

按照上面的回答,关闭任何其他打开的手柄。

vawmfj5a

vawmfj5a3#

我在Mongoose中遇到了同样的问题,但在我的情况下,在afterAll中调用disconnect并没有做出改变。但是在beforeAll中添加基于promise的setTimeout确实有效。但是我不是定时器的粉丝,并设法像这样修复了它。👇

beforeAll(async () => {
  await mongoose.disconnect();
  await mongoose.connect(MONGODB_URL, MONGODB_OPTIONS);
});

以上的变通方法对我来说感觉更自然,希望对你有帮助。

qhhrdooz

qhhrdooz4#

2023年4月更新-新增openHandlesTimeout选项

jest 29.5.0添加了一个新的openHandlesTimeout选项
openHandlesTimeout [number]默认值:1000
如果Jest在完成后的毫秒数内没有干净地退出,则打印一个警告,指出可能存在打开的句柄。使用0禁用警告。

  • 理想情况下,您仍然应该关闭任何打开的句柄,但在许多情况下,句柄(如TCP套接字)会自行关闭,它们所需的时间比jest预期的要长一点。
  • 如果你现在正在添加await sleep(3 * SECONDS)或类似的句柄来关闭,你现在可以在配置中设置openHandlesTimeout来避免这些黑客攻击。
  • 如果你不关心警告,只需将openHandlesTimeout设置为0

在我自己的案例中,我有:

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  TLSWRAP

      46 |     options.headers = headers;
      47 |   }
    > 48 |   const response = await fetch(uri, options);
         |                          ^
      49 |
      50 |   let contentType = CONTENT_TYPES.JSON;
      51 |   if (forceResponseContentType) {

      at node_modules/node-fetch/lib/index.js:1468:15

添加:

// https://jestjs.io/docs/configuration#openhandlestimeout-number
openHandlesTimeout: 2 * SECONDS,

到我的jest.config.js使问题消失
SECONDS1000的常数,以避免幻数)。

相关问题