Suites
A unit-testing framework for TypeScript backend systems working with dependency injection. by @omermorad
Docs • Getting Started • Why Suites • Learn Suites
Works with: NestJS (official), Inversify, Vitest, Sinon, Jest, and more
Features
👩💻 Declarative
Suites provides an opinionated declarative API for unit testing: wrap your unit with a single call and receive a correct test environment for the unit’s dependenc…
Suites
A unit-testing framework for TypeScript backend systems working with dependency injection. by @omermorad
Docs • Getting Started • Why Suites • Learn Suites
Works with: NestJS (official), Inversify, Vitest, Sinon, Jest, and more
Features
👩💻 Declarative
Suites provides an opinionated declarative API for unit testing: wrap your unit with a single call and receive a correct test environment for the unit’s dependencies. No more manual mocking and wiring up dependencies.
✅ Type-Safe
All the mocks created by Suites are type-safe, bound to the implementation and allows calling only the correct dependency methods - making sure refactors don’t break your unit tests and there are no silent failures.
🕵️♂️ Smart Mock Tracking
Suites automatically tracks all dependency mocks used during your tests. If a test calls a mocked dependency method that has no return value or missing mock implementation, Suites will warn you immediately — preventing false-negative test failures and hidden logic gaps.
✨ AI Ready
With the concise and type safe format of Suites tests, coding agents (like Claude Code and Cursor) are able to write correct tests in a single pass.
Example
Solitary Mode
Solitary mode is used to evaluate a single unit of work in complete isolation from its external dependencies
import { TestBed, type Mocked } from '@suites/unit';
describe('User Service', () => {
let userService: UserService; // 🧪 The unit we are testing
let userApi: Mocked<UserApi>; // 🎭 The dependency we are mocking
beforeAll(async () => {
// 🚀 Create an isolated test env for the unit
const testBed = await TestBed.solitary(UserService).compile();
userService = testBed.unit;
// 🔍 Retrieve the unit's dependency mock - automatically generated
userApi = testBed.unitRef.get(UserApi);
});
// ✅ Test test test
it('should generate a random user and save to the database', async () => {
userApi.getRandom.mockResolvedValue({id: 1, name: 'John'} as User);
await userService.generateRandomUser();
expect(database.saveUser).toHaveBeenCalledWith(userFixture);
});
}
Sociable Mode
Sociable mode is used to evaluate a single unit of work in a real environment, with some dependencies mocked.
import { TestBed, type Mocked } from '@suites/unit';
describe('User Service', () => {
let userService: UserService; // 🧪 The unit we are testing
let database: Mocked<Database>; // 🎭 The dependency we are mocking
beforeAll(async () => {
// 🚀 Create an isolated test env for the unit
const testBed = await TestBed.sociable(UserService)
.expose(UserApi) // 🔍 The dependency we are exposing
.compile();
userService = testBed.unit;
database = testBed.unitRef.get(Database);
});
// ✅ Test test test
it('should generate a random user and save to the database', async () => {
await userService.generateRandomUser();
expect(database.saveUser).toHaveBeenCalledWith(userFixture);
});
}
Installation
First, install Suites’ unit package:
npm i -D @suites/unit
# or
yarn add -D @suites/unit
# or
pnpm add -D @suites/unit
Then, to fully integrate Suites with your dependency injection framework and testing library, install the corresponding adapters for your project:
npm i -D @suites/doubles.jest @suites/di.nestjs
# or
yarn add -D @suites/doubles.jest @suites/di.nestjs
# or
pnpm add -D @suites/doubles.jest @suites/di.nestjs
DI Frameworks
- NestJS -
@suites/di.nestjs - Inversify -
@suites/di.inversify - TSyringe - Soon!
Testing Libraries
- Jest -
@suites/doubles.jest - Sinon -
@suites/doubles.sinon - Vitest -
@suites/doubles.vitest - Bun - Soon!
- Deno - Soon!
Contributing
We welcome contributions to Suites! Please see the CONTRIBUTING.md file for more information.
Share Your Suites Experience!
Are you using Suites in your projects? We’ve created a community discussion where teams and companies can share how they’re using Suites in production.
👉 Join the discussion and tell us more :)
Your contributions help others discover best practices and see real-world applications of Suites!
Migrating from Automock
If you’re currently using Automock, we’ve created a comprehensive migration guide to help you transition to Suites. The guide covers all the changes and improvements, making the upgrade process smooth and straightforward.
↗️ Migrating from Automock Guide
Your support helps us continue improving Suites and developing new features!
Support the Project
📜 License
Suites is licensed under the Apache License, Version 2.0.