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
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.
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.
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.
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.
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 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);
});
}First, install Suites' unit package:
npm i -D @suites/unit
# or
yarn add -D @suites/unit
# or
pnpm add -D @suites/unitThen, 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- NestJS -
@suites/di.nestjs - Inversify -
@suites/di.inversify - TSyringe - Soon!
- Jest -
@suites/doubles.jest - Sinon -
@suites/doubles.sinon - Vitest -
@suites/doubles.vitest - Bun - Soon!
- Deno - Soon!
We welcome contributions to Suites! Please see the CONTRIBUTING.md file for more information.
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!
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.
Your support helps us continue improving Suites and developing new features!
Suites is licensed under the Apache License, Version 2.0.
