Jest and Mongoose - Jest 检测到打开的句柄

jest and mongoose - jest has detected opened handles

提问人:Rod 提问时间:6/5/2018 最后编辑:CantaRod 更新时间:9/20/2022 访问量:11836

问:

所以我用来测试我的 node.js 应用程序并且测试完成得很好,但我从 jest 收到一条关于打开句柄的消息。有什么见解吗?jest

jest --detectOpenHandles

PASS src/libs/user/tests/user_model_test.js PASS src/tests/app_test.js PASS src/libs/user/tests/user_service_test.js

测试套件:3 次通过,共 3 次 测试:14 次通过,共 14 次 快照:共 0 个 时间:7.209 秒 运行了所有测试套件。

Jest 检测到以下 4 个打开的句柄可能保持 开玩笑退出:

● 承诺

  2 | // we use a test database for testing
  3 | var mongoDB = 'mongodb://localhost/my_db_conn';
> 4 | mongoose.connect(mongoDB);
    |          ^
  5 | const User = require('../user_model');
  6 |
  7 | describe("User model test", () => {

  at NativeConnection.Object.<anonymous>.Connection.openUri (node_modules/mongoose/lib/connection.js:424:19)
  at Mongoose.Object.<anonymous>.Mongoose.connect (node_modules/mongoose/lib/index.js:208:15)
  at Object.<anonymous> (src/libs/user/__tests__/user_model_test.js:4:10)

● 承诺

   8 | });
   9 |
> 10 | module.exports = mongoose.model("User", UserSchema);
     |                           ^

  at Function.init (node_modules/mongoose/lib/model.js:962:16)
  at Mongoose.Object.<anonymous>.Mongoose.model (node_modules/mongoose/lib/index.js:392:11)
  at Object.<anonymous> (src/libs/user/user_model.js:10:27)
  at Object.<anonymous> (src/libs/user/__tests__/user_model_test.js:5:14)

● 承诺

   8 | });
   9 |
> 10 | module.exports = mongoose.model("User", UserSchema);
     |                           ^

  at Function.init (node_modules/mongoose/lib/model.js:962:16)
  at Mongoose.Object.<anonymous>.Mongoose.model (node_modules/mongoose/lib/index.js:392:11)
  at Object.<anonymous> (src/libs/user/user_model.js:10:27)
  at Object.<anonymous> (src/libs/user/index.js:1:41)

● 承诺

  3 | var mongoose = require('mongoose');
  4 | var mongoDB = 'mongodb://localhost/my_db_conn';
> 5 | mongoose.connect(mongoDB);
    |          ^
  6 |
  7 | describe('App test', () => {
  8 |     it('has a module', () => {

  at NativeConnection.Object.<anonymous>.Connection.openUri (node_modules/mongoose/lib/connection.js:424:19)
  at Mongoose.Object.<anonymous>.Mongoose.connect (node_modules/mongoose/lib/index.js:208:15)
  at Object.<anonymous> (src/__tests__/app_test.js:5:10)
猫鼬 jestjs

评论


答:

3赞 Alex Ni 6/6/2018 #1

它与返回 promise 的函数有关。快速修复方法是在创建模型时传递标志,如下所示:model.initskipInit

const User = mongoose.model("users", userSchema, "users", true)

skipInit是此函数中的第四个参数

但在这种情况下,它不会初始化模型的索引,因此最好根据process.env.NODE_ENV

const skipInit = process.env.NODE_ENV === "test" const User = mongoose.model("users", userSchema, "users", skipInit)

评论

1赞 gandra404 6/12/2018
我刚刚开始使用几乎空的项目,没有任何模型并且有同样的错误。所以这至少对我不起作用。
2赞 Zief 8/8/2018
@Alex我使用了你的答案,它有效 - 它可以防止开玩笑抱怨公开的承诺。但是,我不确定它是否有其他问题。在我的实时数据库中,它正确地抱怨重复的电子邮件,因为它是一个唯一的字段。在我的测试数据库中,通过mockgoose,它没有错误。我只能假设因为设置了skipInit = false,但我正在继续调查
8赞 Kenneth Mitchell De Leon 6/28/2018 #2

测试后,您的猫鼬连接似乎仍然打开,请尝试以下方法之一:

  1. 测试后关闭服务器实例。

    const server = require('./app'); //server instance    
    server.close(); //put in afterAll or afterEach depending on your test
    
  2. 完成所有测试后,请关闭数据库连接。

    afterAll(()=>{ mongoose.connection.close();});
    
  3. 用 async/await 包装你的 Mongoose 连接。

    async function(){
       await mongoose.connect(mongoDB);
    };
    

尝试一种或组合。 这些是我的解决方案,因为我无法真正看到您的代码。

评论

0赞 Sherif eldeeb 7/12/2021
这会导致 stackoverflow.com/questions/68340573/... @kennethcauses Matcher error
3赞 pavittarx 8/21/2021
添加后,我仍然收到mongoose.connect的openHandles错误mongoose.connection.close()
0赞 Bruno da Silva 9/4/2021
@pavittarx确保您还执行了上述步骤 3。async/await 在连接件上。
1赞 Fiehra 2/16/2022
不幸的是,这在 2022 年对我不起作用,错误仍然存在
10赞 Fiehra 2/16/2022 #3

经过几个小时的搜索,我找到了有关 SO 和 github 问题的解决方案,https://github.com/visionmedia/supertest/issues/520 遇到了这个 github 线程,其中提供了多种解决方案。最终对我有用的是在我的根目录中实现一个全局拆解文件,如下所示:

// test-teardown-globals.js
module.exports = () => {
  process.exit(0);
};

并且还可以稍微调整我的jest.config.js

// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  globalTeardown: '<rootDir>/test-teardown-globals.js',
};

更新:另请注意@SimonSimCity的评论,此解决方案需要一些权衡。考虑使用 Özgür Atmaca 的答案,断开猫鼬连接。

评论

1赞 Ondiek Elijah 3/23/2022
神奇!您的回答使我免于几个小时的疯狂调试和搜索修复程序,直到 Google 的第 3 页。工程!!
1赞 Fiehra 4/14/2022
很高兴我能够为你做到这一点:D
6赞 SimonSimCity 5/3/2022
谨慎:通过使用它,您的进程将始终具有返回代码,即使测试失败也是如此!通常,该命令会在出错时返回。😬 背景:大多数系统依靠返回代码来确定命令是否成功运行。01
0赞 Fiehra 8/9/2022
谢谢你的提醒!因此,此解决方案仅适用于我计算机上的本地测试,而不适用于在服务器管道上运行的测试?@SimonSimCity
2赞 SimonSimCity 8/11/2022
@Fiehra没错。我也不会在本地使用它。我以艰难的方式学到了它,并且需要大量的时间才能在这次事件之后再次获得对 CI 管道和流程的信任......
4赞 Liger 9/11/2022 #4

我在 Mongoose 上遇到了同样的问题,并设法像这样👇修复它

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

我发现的大多数“解决方案”都是围绕计时器的,我不喜欢用计时器解决问题,所以上面的解决方法对我来说感觉更自然,希望它有所帮助。

评论

0赞 hurricane 9/15/2022
也许在断开连接之前检查当前状态也很好。mongoose.connection.readyState
1赞 Grant mitchell 9/18/2022
我不知道这是如何工作的,但它确实有效