Testcontainers中Mongo初始化脚本执行失败问题排查
Testcontainers MongoDB集成测试:解决初始化脚本"not primary"问题
问题根源
你遇到的问题确实是初始化脚本执行时机早于副本集就绪。Testcontainers启动的MongoDB默认以副本集模式运行,而/docker-entrypoint-initdb.d/下的脚本会在MongoDB进程启动后立即执行,此时副本集还没完成节点选举,当前节点还不是primary,执行创建用户、写入数据等操作就会触发"not primary"异常。
正确的初始化脚本内容
核心是在脚本开头加入等待副本集primary节点就绪的逻辑,确保后续操作在主节点可用时执行:
// 等待副本集primary节点就绪 function waitForPrimary() { while (true) { const status = rs.status(); // status.ok=1表示副本集状态正常,myState=1表示当前节点是primary if (status.ok === 1 && status.myState === 1) { break; } print("等待副本集primary节点就绪..."); sleep(1000); // 每秒检查一次 } } // 先等待就绪,再执行初始化操作 waitForPrimary(); // 创建管理员用户(示例) db.getSiblingDB("admin").createUser({ user: "admin", pwd: "admin@123", roles: [{ role: "root", db: "admin" }] }); // 预填充业务数据(示例) const myDb = db.getSiblingDB("my_test_db"); myDb.users.insertOne({ username: "test_user", email: "test@example.com" });
额外注意事项
- Testcontainers的MongoDB容器会自动完成副本集的初始化配置,不需要在脚本中手动执行
rs.initiate() - 如果你的测试代码中自定义了副本集名称,脚本中的
rs.status()会自动识别,无需额外修改 - 脚本中的
sleep()是MongoDB shell内置函数,无需额外依赖
内容的提问来源于stack exchange,提问作者florin
相关产品推荐
相关产品推荐

