You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker下Jest测试Mongoose Model查询超时但原生查询正常

故障概述
  • 故障场景:Docker容器环境下运行Jest测试用例时突发Mongoose异常,应用与测试服务此前长期稳定运行
  • 异常表现:Mongoose可正常建立MongoDB连接,执行原生驱动层面的集合查询mongoose.connection.collection("users").findOne()可正常返回结果,但调用已注册的User模型方法(如User.findOne())时会持续阻塞,最终触发超时错误
  • 复现差异:User模型在主应用中运行正常,相同环境配置下其他同事的个人电脑运行同一套测试用例无异常
  • 已尝试无效操作:从零重建Docker镜像、执行docker system prune清理环境、手动删除所有镜像与数据卷、多次清空~/.docker目录,均未解决问题
调试相关代码

测试用例代码

import mongoose from 'mongoose'
import User from '../models/User.mjs';

describe('Debug', () => {

  test('test DB', async () => {
    await mongoose.connect("mongodb://mongo:27017/test", {});
    console.log("Ready state: " + mongoose.connection.readyState);
    console.log(await mongoose.connection.collection("users").findOne());
    console.log(User);
    console.log(await User.findOne());
    await mongoose.disconnect();
  })

})

User模型定义

import mongoose from 'mongoose'
import bcrypt from 'mongoose-bcrypt'

const UserSchema = new mongoose.Schema({
  ...fields-omitted
}, { timestamps: true })

export default mongoose.model('User', UserSchema);

运行报错输出

pptruser@b6cad840e3ca:/app$ npm test -- debug.test.js

> debug-test@1.0.0 test
> JEST_PUPPETEER_CONFIG=tests/jest-puppeteer.config.cjs node --experimental-vm-modules ./node_modules/.bin/jest --detectOpenHandles --runInBand "debug.test.js"

(node:2647) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
  console.log
    Ready state: 1

      at Object.<anonymous> (tests/debug.test.js:8:13)

  console.log
    {
      _id: new ObjectId("629dcc09a5c0753289a9e83a"),
      type: 'User',
      phoneNumber: '+1111111111',
      phoneNumberVerified: false,
      firstname: 'John',
      lastname: 'Doe',
      email: 'john.doe@test.at',
      username: '',
      provider: '',
      authToken: '',
      token: 'mDiQrWKFIPXO3VfvHbToAaEg',
      failedAuthCounter: 0,
      birthDate: 1950-01-01T00:00:00.000Z,
      rights: [],
      expireToken: 2022-06-06T09:42:33.155Z,
      createdAt: 2022-06-06T09:42:33.156Z,
      updatedAt: 2022-06-06T09:42:33.156Z,
      __v: 0
    }

      at Object.<anonymous> (tests/debug.test.js:9:13)

  console.log
    Model { User }

      at Object.<anonymous> (tests/debug.test.js:10:13)

 FAIL  tests/debug.test.js (5.59 s)
  Debug
    ✕ test DB (5001 ms)

  ● Debug › test DB

    thrown: "Exceeded timeout of 5000 ms for a test.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

      4 | describe('Debug', () => {
      5 |
    > 6 |   test('test DB', async () => {
        |   ^
      7 |     await mongoose.connect("mongodb://mongo:27017/test", {});
      8 |     console.log("Ready state: " + mongoose.connection.readyState);
      9 |     console.log(await mongoose.connection.collection("users").findOne());

      at tests/debug.test.js:6:3
      at tests/debug.test.js:4:1

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        5.64 s, estimated 6 s
Ran all test suites matching /debug.test.js/i
排查方向
  • 优先排查mongoose-bcrypt原生依赖兼容问题:原生驱动查询正常、模型查询阻塞,最高概率是Schema挂载的插件在执行阶段卡住。先注释掉User模型中mongoose-bcrypt的引入和注册,再跑测试用例,如果恢复正常,就是bcrypt原生模块和当前Docker环境的Node版本、CPU架构不兼容——这类原生C++扩展会在npm install时针对当前运行环境编译,跨架构(比如arm宿主机拉了x86镜像、或者镜像Node版本和编译时的版本不匹配)时不会直接抛启动错误,只会在实际调用哈希计算逻辑时死锁阻塞。
  • 排查Mongoose模型重复注册问题:你启动测试时加了--experimental-vm-modules参数,ESM模块和Jest的VM环境搭配时偶发会出现模块缓存失效,导致同一个Schema被重复注册到未建立连接的Mongoose实例上,模型和当前活跃连接不绑定,调用方法时会一直等待无响应。可以在调用User.findOne()前打印User.db === mongoose.connection验证是否为同一个连接实例,如果返回false,在connect之后先执行mongoose.deleteModel('User')重新注册模型即可验证。
  • 排查全局钩子阻塞问题:检查是否有全局挂载的Mongoose pre钩子(比如pre('find')/pre('init'))中存在未resolve的异步逻辑,或者钩子依赖的模块在测试环境加载异常导致执行卡住,可以给每个pre钩子加入口日志,确认执行卡在哪一步。

内容的提问来源于stack exchange,提问作者Somebody25

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 20:36:21