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

gan*_*404 5 tdd node.js jestjs

刚刚开始使用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  
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

知道如何解决吗?

这是github上的相关问题:https : //github.com/facebook/jest/issues/6446

tks*_*con 9

这是我为解决这个问题所做的事情。

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

然后我在出现问题的特定测试中设置了 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);
  });
});
Run Code Online (Sandbox Code Playgroud)

如上所述,关闭所有其他打开的句柄。

  • 看起来jest的异步关闭操作是在服务器关闭之前调用的。超时有助于增加一些缓冲时间来延迟关闭操作。 (2认同)

Est*_*ask 6

detectOpenHandlesoption 用于检测打开的句柄,应该正常使用。该错误警告可能打开的句柄:

Jest 检测到以下 4 个可能阻止 Jest 退出的打开句柄

即使将关闭句柄,错误仍会出现。

此应用程序的实际问题是数据库连接并未真正关闭:

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

出于某种原因NODE_ENVdev,尽管文档指出它应该是test.

在应用程序启动时立即关闭数据库连接可能会导致实际使用数据库连接的单元出现问题。如指南中所述,MongoDB 连接应在测试结束时。由于使用了默认的 Mongoose 连接,它可以是:

afterAll(() => mongoose.disconnect());
Run Code Online (Sandbox Code Playgroud)


mik*_*ana 5

2023 年 4 月更新 - 新openHandlesTimeout选项

\n

jest 29.5.0 添加了一个新openHandlesTimeout选项

\n
\n

openHandlesTimeout [数量]\n默认值:1000

\n

打印一条警告,指示如果 Jest 在完成后的毫秒数内未完全退出,则可能存在打开的句柄。使用 0 禁用警告。

\n
\n
    \n
  • 理想情况下,您仍然应该关闭所有打开的句柄,但是在许多情况下,句柄(如 TCP 套接字)会自行关闭,只是比笑话预期的时间要长一点。
  • \n
  • 如果您当前正在添加await sleep(3 * SECONDS)或类似的要关闭的句柄,您现在只需openHandlesTimeout在配置中进行设置即可避免这些黑客行为。
  • \n
  • 如果您不关心警告,只需将其设置openHandlesTimeout0.
  • \n
\n

就我自己而言,我有:

\n
Jest has detected the following 1 open handle potentially keeping Jest from exiting:\n\n  \xe2\x97\x8f  TLSWRAP\n\n      46 |     options.headers = headers;\n      47 |   }\n    > 48 |   const response = await fetch(uri, options);\n         |                          ^\n      49 |\n      50 |   let contentType = CONTENT_TYPES.JSON;\n      51 |   if (forceResponseContentType) {\n\n      at node_modules/node-fetch/lib/index.js:1468:15\n
Run Code Online (Sandbox Code Playgroud)\n

添加:

\n
// https://jestjs.io/docs/configuration#openhandlestimeout-number\nopenHandlesTimeout: 2 * SECONDS,\n
Run Code Online (Sandbox Code Playgroud)\n

我的jest.config.js 让问题消失

\n

SECONDS是一个常数,1000以避免幻数)。

\n