【问题标题】:Why doesn't Jest complete the async operation(s) in this Node test?为什么 Jest 没有完成这个 Node 测试中的异步操作?
【发布时间】:2019-04-15 10:54:34
【问题描述】:

我有以下简单的测试设置:

test('what did I do to deserve this', async () => {
  expect.assertions(1)

  const data = await fetchData() // or fetchData2 
  expect(data).toBe('peanut butter')
})

async function fetchData () {
  return "peanut butter"
}

async function fetchData2 () {
  return knex.select('name').from('foos')
}

当我使用fetchData时,玩笑愉快地结束了。
但是当我使用fetchData2 时,它会抱怨:

Jest 在测试运行完成后一秒没有退出。

这通常意味着存在未执行的异步操作 在您的测试中停止。考虑运行 Jest --detectOpenHandles 解决此问题。

data 变量确实有 db 查询的结果,API 中更高级别的其他调用者可以很好地解析查询并继续执行其他语句。

我试过了:

  1. --detectOpenHandles 标志,但它没有显示任何内容。
  2. fetchData2 制作期望通行证,以防它是the issue described here
  3. done arg 传递给test 中的异步函数。它确实存在,但调用它并不能修复警告。
  4. 向它抛出 try/catch 块

感谢您提供的帮助。

事物的版本:

  • 节点 v11.1.0
  • “笑话”:“^23.6.0”
  • “knex”:“^0.15.2”

【问题讨论】:

    标签: node.js jestjs knex.js


    【解决方案1】:

    遇到这些错误:

    1.

    一个工作进程未能正常退出并被强制 退出。这可能是由于测试不正确导致的 拆除。尝试使用 --detectOpenHandles 运行以查找泄漏。

    Jest 在测试运行完成后一秒没有退出。

    这通常意味着存在未执行的异步操作 在您的测试中停止。考虑运行 Jest --detectOpenHandles 解决此问题。 节点:内部/进程/承诺:246 triggerUncaughtException(err, true /* fromPromise */); ^

    [UnhandledPromiseRejection:此错误源于抛出 在没有 catch 块的异步函数内部,或通过拒绝 未使用 .catch() 处理的承诺。承诺被拒绝 原因“错误:请求失败,状态码为 404”。] { 代码: 'ERR_UNHANDLED_REJECTION' } ##[error]Cmd.exe 以代码“1”退出。

    全局设置和拆卸示例:

    // setup.js
    const knexConfiguration = require('../config/knex')[process.env.NODE_ENV];
    const knex = require('knex');
    
    const setup = async () => {
      const client = knex(knexConfiguration)
      await client.migrate.latest();
      await client.destroy();
    };
    
    module.exports = setup;
    
    // teardown.js
    const knexConfiguration = require('../config/knex')[process.env.NODE_ENV];
    const knex = require('knex');
    
    const teardown = async () => {
      const client = knex(knexConfiguration)
      await client.migrate.rollback();
      await client.destroy();
    };
    
    module.exports = teardown;
    

    来源:

    https://github.com/facebook/jest/issues/7287#issuecomment-510068325

    另一个例子:

    dbConnection.js

    export default new Sequelize({...}); // The Sequelize instance.
    

    some.spec.js

    import dbConnection from './dbConnection';
    
    const { SomeModel } = dbConnection.models;
    
    describe('...', () => {
      beforeEach(async () => {
          await SomeModel.create({...});
      });
      ...
    });
    
    afterAll(async done => {
      // Closing the DB connection allows Jest to exit successfully.
      dbConnection.close();
      done();
    });
    

    https://github.com/facebook/jest/issues/7287#issuecomment-434058564

    【讨论】:

      【解决方案2】:

      强制关闭 Jest 而不是 DB Connection:

      --forceExit
      

      所以我的测试脚本看起来像这样,

      "scripts": {
              "test": "jest --forceExit"
          }
      

      【讨论】:

      • 这可行,但现在我看到:“强制退出 Jest:您是否考虑过使用 --detectOpenHandles 来检测在所有测试完成后继续运行的异步操作?”
      【解决方案3】:

      您需要在测试套件末尾调用knex.destroy() 来拆除连接池。

      【讨论】:

      猜你喜欢
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-01
      • 2019-01-18
      • 2020-08-26
      • 2014-05-15
      相关资源
      最近更新 更多