Django-style test DBs in NestJS: my MikroORM integration test helper (PoC)
2025-09-11
2025-09-11
Coming from Django, I missed the “it just works” test database story: tests can run real queries against a real DB with migrations applied automatically. In the TypeScript ecosystem, this is usually not “default behavior”, so I built a small helper for NestJS + MikroORM that gives me a Django-like workflow for integration tests while keeping unit tests fast and DB-free.
In Django, the test runner and ORM are part of one cohesive stack:
In many TS backends (NestJS + ORM + Jest/Vitest), the ecosystem is more modular. NestJS doesn’t own your ORM; the ORM doesn’t own your test runner; and the test runner doesn’t own your DB lifecycle. Result: you assemble your own conventions.
A few reasons (none are “bad”, it’s mostly ecosystem shape):
So instead of waiting for a universal solution, I created a small helper that matches my needs.
In this PR, I added a tiny utility class that:
*_test database,Key idea: unit tests stay unit tests (fast, mocked). Integration tests opt into “real DB”.
The helper lives at test/utils/database-test.ts and builds a MikroORM config from your app config, but with a test dbName and the migrator enabled. It ensures the database exists and migrates it.
Important implementation details from the PoC:
dbName becomes ${commonMikroOrmConfig.dbName}_testextensions: [Migrator] enables migrationsensureDatabase() creates the DB if missinggetMigrator().up() applies pending migrationsteardown closes the connection but keeps the database contentI added posts.integration.spec.ts as a minimal integration test showing how it feels to use: 
beforeAll: orm = await DatabaseTest.init()afterAll: await DatabaseTest.close()This test demonstrates real persistence + retrieval via the DB. It also includes a second test that asserts data is still there (“keeps data between tests”). This is just here to demonstrate the default behavior but in a real world project it would be a good idea to delete the created data after each test case.
This is explicitly a PoC, and it has important caveats:
If I were to evolve this from PoC to “real project quality”, I’d add:
Django made “real DB tests” feel boring—in a good way. In NestJS + MikroORM, I had to assemble the story myself. This helper is small, explicit, and already valuable for integration tests where real queries matter.
PoC source: PR #1 in abel-castro/blog-nest .