如何在Mocha测试套件启动前等待异步数据库迁移完成?
Great question! Dealing with async setup like database migrations before Mocha runs tests is a common pain point, and there are a few solid strategies besides forcing sync operations. Here are your best options:
1. Use a Root-Level before Hook
Mocha automatically waits for async hooks to resolve before executing tests. You can register a global before hook directly in your bootstrap.js file, which will run once before any test suites start:
const runMigrations = require('./path-to-your-migration-function'); // Register a root-level async before hook before(async function() { // Increase timeout if migrations take longer than Mocha's default (2000ms) this.timeout(60000); // 60 seconds await runMigrations(); });
When you start Mocha with mocha --require bootstrap.js, it will detect this hook and wait for the migration promise to resolve before launching your tests. This works well if you need to add other setup steps alongside migrations.
2. Use Mocha's --delay Flag for Manual Control
The --delay flag tells Mocha to pause test execution until you explicitly call mocha.run(). This gives you full control over when tests start, perfect for complex async workflows:
First, start Mocha with the flag:
mocha --delay --require bootstrap.js
Then in bootstrap.js:
const runMigrations = require('./path-to-your-migration-function'); const mocha = require('mocha'); async function setup() { try { await runMigrations(); // Migrations succeeded — kick off tests mocha.run(); } catch (err) { console.error('Migration failed:', err); process.exit(1); // Exit with error code to avoid running tests on invalid DB state } } setup();
3. Export a Promise from bootstrap.js
Mocha (v8.0+) supports waiting for a promise exported by the required bootstrap module. This is the most concise approach for simple async setup:
CommonJS Example:
const runMigrations = require('./path-to-your-migration-function'); // Export the migration promise — Mocha will wait for it to resolve module.exports = runMigrations();
ES Module Example:
import runMigrations from './path-to-your-migration-function'; export default runMigrations();
If the promise rejects (migration fails), Mocha will abort test execution automatically.
Key Notes for All Strategies:
- Error Handling: Always catch migration failures to avoid running tests against an uninitialized database.
- Timeout Adjustments: Migrations can take time — use
this.timeout()in hooks or the--timeoutCLI flag to prevent premature test failures. - Cleanup: Consider adding a root-level
afterhook to roll back migrations or clean up resources after tests finish.
内容的提问来源于stack exchange,提问作者Marco Talento

