@neoma/managed-database
v0.1.0
Published
A managed database fixture for Jest testing (unit, integration etc)
Maintainers
Readme
@neoma/managed-database
A managed database fixture for NestJS integration testing with TypeORM. Automatically handles in-memory SQLite database lifecycle for Jest tests.
Motivation
Integration testing NestJS applications with TypeORM requires setting up and tearing down database connections for each test. This package eliminates the boilerplate by:
- Automatically managing a single DataSource instance across tests
- Using in-memory SQLite for fast, isolated test execution
- Handling initialization and cleanup via Jest lifecycle hooks
- Auto-discovering entities from your project structure
Problem / Solution
Without @neoma/managed-database
import { DataSource } from "typeorm"
import { User } from "./user.entity"
import { Post } from "./post.entity"
describe("UserRepository", () => {
let dataSource: DataSource
beforeEach(async () => {
// Manually create and initialize datasource for each test
dataSource = new DataSource({
type: "sqlite",
database: ":memory:",
entities: [User, Post], // Must manually list all entities
synchronize: true,
})
await dataSource.initialize()
})
afterEach(async () => {
// Manually destroy datasource after each test
await dataSource.destroy()
})
it("should create a user", async () => {
const repo = dataSource.getRepository(User)
// Test code...
})
})With @neoma/managed-database
import { managedDatasourceInstance } from "@neoma/managed-database"
import { User } from "./user.entity"
describe("UserRepository", () => {
it("should create a user", async () => {
// Get the managed instance - lifecycle handled automatically!
const dataSource = managedDatasourceInstance()
const repo = dataSource.getRepository(User)
const user = await repo.save({ username: "alice" })
expect(user.id).toBeDefined()
})
it("gets a fresh database for each test", async () => {
// Each test starts with a clean database
const dataSource = managedDatasourceInstance()
const repo = dataSource.getRepository(User)
const users = await repo.find()
expect(users).toHaveLength(0) // Always starts empty
})
})Installation
1. Install the package
npm install --save-dev @neoma/managed-database2. Install peer dependencies
npm install --save-dev sqlite3 typeorm @nestjs/typeorm
npm install @nestjs/common @nestjs/core3. Import in your test files
import { managedDatasourceInstance } from "@neoma/managed-database"That's it! The package automatically registers Jest hooks when imported, so your database lifecycle is managed automatically.
Basic Usage
Repository Testing
import { managedDatasourceInstance } from "@neoma/managed-database"
import { User } from "./user.entity"
describe("User Repository", () => {
it("should create and retrieve users", async () => {
const dataSource = managedDatasourceInstance()
const userRepo = dataSource.getRepository(User)
const user = await userRepo.save({
username: "alice",
})
const found = await userRepo.findOne({ where: { id: user.id } })
expect(found.username).toBe("alice")
})
})Testing Services
import { managedDatasourceInstance } from "@neoma/managed-database"
import { UserService } from "./user.service"
import { User } from "./user.entity"
describe("UserService", () => {
let service: UserService
beforeEach(() => {
const dataSource = managedDatasourceInstance()
service = new UserService(dataSource.getRepository(User))
})
it("should create users", async () => {
const user = await service.create({ username: "alice" })
expect(user.id).toBeDefined()
})
})API Reference
managedDatasourceInstance(): DataSource
Returns the managed DataSource instance for the current test.
Returns: DataSource - A TypeORM DataSource instance configured with in-memory SQLite
Lifecycle:
- Automatically initialized before each test via
beforeEachhook - Automatically destroyed after each test via
afterEachhook - Returns the same instance within a single test
- Returns a fresh instance for each new test
Example:
const dataSource = managedDatasourceInstance()
const repo = dataSource.getRepository(User)Note: The lifecycle hooks are registered automatically when you import anything from this package, so you don't need to call any setup functions.
datasource(): Promise<DataSource>
Low-level function to create a new DataSource instance. Used internally by managedDatasourceInstance().
Returns: Promise<DataSource> - A new, initialized DataSource instance
Configuration:
- Type: SQLite
- Database: In-memory (
:memory:) - Entities: Auto-discovered from
src/**/*.entity.ts - Synchronize: Enabled (auto-creates schema)
Configuration
Entity Discovery
The package automatically discovers entities from:
src/**/*.entity.tsThis pattern will find all entity files in your src directory and subdirectories. Ensure your entities:
- Use the
.entity.tsnaming convention - Are located under the
src/directory - Export classes decorated with
@Entity()
Example Structure:
src/
├── user.entity.ts
├── post.entity.ts
└── modules/
└── auth/
└── session.entity.tsAll three entities (User, Post, Session) will be automatically discovered.
Database Configuration
The package uses the following TypeORM configuration:
{
type: "sqlite",
database: ":memory:",
entities: ["src/**/*.entity.ts"],
synchronize: true,
}Key Features:
- SQLite In-Memory: Each test gets a completely isolated database
- Auto-Sync: Schema is automatically created from your entities
- Fast: In-memory databases are extremely fast for testing
- Clean State: Every test starts with a fresh, empty database
Why SQLite In-Memory?
Testing with SQLite in-memory provides several advantages:
- Speed: Orders of magnitude faster than traditional databases
- Isolation: Each test gets a completely independent database
- Portability: No external database setup required
- CI/CD Friendly: Works out of the box in any environment
- Consistency: Deterministic test behavior
Requirements
- Node.js >= 22.0.0
- Jest testing framework
- TypeScript >= 5.0
- NestJS >= 11.0
- TypeORM >= 0.3
Links
Related Packages
- @neoma/managed-app - Managed NestJS app instances for E2E testing
License
MIT
Built with love by Shipdventures for the NestJS community.
