Testing-first utilities for applications built with @elsikora/cladi.
@elsikora/cladi-testing keeps test setup explicit and composable while reducing repeated wiring for common test scenarios.
- create a dedicated DI container for each test suite or case
- compose plain and decorator modules with one helper
- build deterministic value/factory mocks with typed tokens
- override providers in-place for scenario-specific tests
- reset and dispose resources safely between test runs
npm install -D @elsikora/cladi @elsikora/cladi-testingCompatibility:
@elsikora/cladi-testingrequires@elsikora/cladi >= 2.1.0
createTestingContainer()JSDocmockProvider()JSDocoverrideProvider()JSDocresetTestingContainer()JSDoccomposeTestingModules()JSDoc
import { createModule, createToken } from "@elsikora/cladi";
import { createTestingContainer, mockProvider, overrideProvider, resetTestingContainer } from "@elsikora/cladi-testing";
interface IUserRepository {
findNameById(id: string): string | undefined;
}
interface IUserService {
readName(id: string): string;
}
const UserRepositoryToken = createToken<IUserRepository>("UserRepository");
const UserServiceToken = createToken<IUserService>("UserService");
const appModule = createModule({
exports: [UserServiceToken],
providers: [
mockProvider(UserRepositoryToken, { findNameById: () => "Alice" }),
{
deps: [UserRepositoryToken],
provide: UserServiceToken,
useFactory: (repository: IUserRepository): IUserService => ({
readName: (id: string): string => repository.findNameById(id) ?? "unknown",
}),
},
],
});
const container = createTestingContainer({
modules: [appModule],
shouldValidateOnCreate: true,
});
console.log(container.resolve(UserServiceToken).readName("u1")); // "Alice"
await overrideProvider(container, mockProvider(UserRepositoryToken, { findNameById: () => "Bob" }));
console.log(container.resolve(UserServiceToken).readName("u1")); // "Bob"
await resetTestingContainer(container);import { beforeEach, afterEach, describe, it, expect } from "vitest";
import { createTestingContainer, resetTestingContainer } from "@elsikora/cladi-testing";
let container: ReturnType<typeof createTestingContainer>;
beforeEach(() => {
container = createTestingContainer({ shouldValidateOnCreate: true });
});
afterEach(async () => {
await resetTestingContainer(container);
});
describe("my feature", () => {
it("resolves dependencies", () => {
expect(container).toBeDefined();
});
});createTestingContainer(options?)- create and preconfigure a test container.mockProvider(token, valueOrFactory, options?)- build typed value/factory mocks.overrideProvider(container, provider)- replace provider registration for a token.resetTestingContainer(container)- dispose container and resource graph.composeTestingModules(container, modules)- compose plain and decorator modules.
Detailed behavior and signatures:
The package follows clean architecture boundaries:
domain: contracts, options, and shared typesapplication: provider-building use-case utilitiesinfrastructure: default constants and low-level detailspresentation: public API used directly in tests
Entrypoint:
src/index.ts
npm run lintnpm run lint:typesnpm run test:unitnpm run test:e2enpm run test:allnpm run build
MIT