npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@integration-testing/data-isolation

v0.1.2

Published

Transactional database integration tests for Jest and Vitest with Prisma, pg, and TypeORM

Readme

@integration-testing/data-isolation

Write isolated database integration tests with a consistent API across supported test runners and database clients.

Your repository test inserts a product, updates its stock, and checks the result. The test passes. But the product is still in the database. Run the test again and the same SKU may already exist; run another test and it may see data left behind by the first.

Now every test needs a cleanup strategy: delete the rows it created, handle foreign keys in the right order, and make sure cleanup still runs when an assertion fails.

Give each test a transaction, then roll back its writes automatically.

That is what this library provides through rollback-only transactions. After your application's real migrations have prepared the database, each test gets its own transaction. Its fixtures, test body, and teardown use the same transaction-scoped client. When the attempt finishes, the library rolls back those writes, whether the test passed or failed. You do not write per-test DELETE cleanup for operations made through that client.

Configure your database and test runner once, then choose one of the two declarations below for each transactional test file. Both use the same shared context and runner setup.

Option 1: annotation

Add @DataIntegrationTest to a marker class in the test file, then write ordinary tests:

import { DataIntegrationTest } from '@integration-testing/data-isolation';
import { dataContext } from './data-context.js';

@DataIntegrationTest
export class ProductRepositoryTest {}

test('creates a product', async () => {
  const client = dataContext.getCurrentContext().client;
  await client.query('INSERT INTO products (sku, stock) VALUES ($1, $2)', ['book', 10]);
  const result = await client.query('SELECT stock FROM products WHERE sku = $1', ['book']);
  expect(result.rows[0].stock).toBe(10);
}); // The insert is rolled back, including when the assertion fails.

The annotation activates the entire file, including nested suites. The class is only a marker; keep test bodies in your runner's test() or it() calls.

Option 2: without decorators

Call declareDataIntegrationTest() at the top level of the test file instead of adding a marker class:

import { declareDataIntegrationTest } from '@integration-testing/data-isolation';
import { dataContext } from './data-context.js';

declareDataIntegrationTest();

test('creates a product', async () => {
  const client = dataContext.getCurrentContext().client;
  await client.query('INSERT INTO products (sku, stock) VALUES ($1, $2)', ['book', 10]);
  const result = await client.query('SELECT stock FROM products WHERE sku = $1', ['book']);
  expect(result.rows[0].stock).toBe(10);
}); // The insert is rolled back, including when the assertion fails.

Both examples use pg and your runner's globals after one-time setup. They have the same transaction behavior: beforeEach, the test, and afterEach share a client, followed by rollback. Use exactly one declaration per test file; do not combine the two forms. Neither declaration replaces the database and runner setup.

Two tools that work hand in hand

Real infrastructure with @integration-testing/testcontainers, isolated test data with @integration-testing/data-isolation.

| Tool | Responsibility | | --- | --- | | Testcontainers Integration | Start disposable infrastructure and stop it after the run | | Data Isolation | Give each test a transaction-scoped client and roll back its writes | | Your application | Apply its real migrations before test workers start and pass the scoped client to repositories |

Start with the paired PostgreSQL example, which uses the published @integration-testing/[email protected] package. Both tools remain independent: an existing test database, Docker Compose, or a CI database service can also supply the connection URL.

Install and configure once

For the 0.1.2 release, install:

npm install --save-dev @integration-testing/[email protected]

The lifecycle is database-independent: configure a transaction adapter for your database client.

Requires Node.js 22.22+. Supports Vitest 4.1.x, Jest 30.x, pg 8.x, and TypeORM 0.3.x. Install only the runner and database client you use; runner and driver dependencies stay optional. Core, database adapters, and Jest integration support ESM and CommonJS; the Vitest integration uses ESM. Before npm publication, use the local archive instructions.

  1. Export a shared context with createDataIntegrationTestContext(configuration).
  2. Install that context in your runner setup. Jest also requires the package's /jest/environment.
  3. Run your application's real migrations before workers start.
  4. Add @DataIntegrationTest or declareDataIntegrationTest() to each test file and use dataContext.getCurrentContext().client.

The setup guide provides complete files and commands. Choose your runnable example below to see the wiring in context.

Examples

These projects live in this repository and are not shipped to npm. Each example README explains its prerequisites and commands; the links to setup files show the actual implementation.

| What you want to do | Runnable example and setup | | --- | --- | | Declare a file with @DataIntegrationTest | Annotation example | | Declare a file without decorators | Function example | | Start PostgreSQL with Testcontainers and use pg + Vitest | Small paired example, database context | | Use pg, Prisma, or TypeORM with Jest and Vitest | NestJS inventory application, shared context | | Configure Jest | Jest configuration, setup | | Configure Vitest | Vitest configuration, setup | | Use an existing PostgreSQL URL without Testcontainers | Inventory run instructions: test:external | | Try Prisma + SQLite without Docker | Small SQLite example, inventory SQLite mode | | Inject a transaction-bound client into NestJS repositories | Provider overrides, repository implementations | | Apply real application migrations once | Inventory migrations and launcher | | Compare with handwritten transaction hooks | Comparison, pg baseline for both runners |

The inventory example exercises the same application behavior across clients and runners, including constraints, multi-write operations, and rollback verified from an independent connection. Its installed-package check copies the project outside the workspace and installs a packed archive. See consumer verification.

What it does and does not do

Use this library for direct database and repository tests whose operations can use the supplied transaction client.

| The library handles | Your application supplies | | --- | --- | | A new transaction for each test attempt, including retries | A reachable test database and real application migrations | | One typed client across beforeEach, the test, and afterEach | Awaited operations using that client | | Rollback after passing and failing tests, with cleanup failures reported | Repository or NestJS provider wiring | | Jest and Vitest lifecycle integration | A shared context and the runner setup |

Rollback covers awaited operations using the supplied transaction client. The library does not patch production clients or automatically capture other connections, HTTP requests, background jobs, explicit commits, or nontransactional database operations. It does not undo messages, files, or other external effects.

Run real migrations once before workers for a shared database. prepareDatabase is per file, so it is not the place for shared schema preparation. beforeAll and afterAll are outside per-test transactions. Tests within a file must run sequentially; .concurrent and callback-style done tests/hooks are unsupported. Parallel files still need fixtures that account for database locks and shared state. Runner timeouts cannot forcibly cancel arbitrary JavaScript.

The core can be integrated with other runners, but Cucumber and custom harnesses need their own runner adapter. A declaration alone does not supply that integration.

Ordinary rollback hooks can be enough for a small suite. This library provides a reusable typed context and consistent lifecycle and failure reporting across supported runners and clients. No performance or maintenance savings are claimed without measurement.

For details, see the rollback boundaries, API and troubleshooting, and Testcontainers resource handoff.

Contributing and release checks

bun install --frozen-lockfile
bun run verify                 # Build, types, lint, runner tests, SQLite, package checks
bun run test:consumer           # Installed consumer matrix; PostgreSQL requires Docker

See the release guide for the complete release gates and publication steps.

MIT license.