Mock Configuration

Suites provides two methods for configuring mock behavior:

  • .mock().final() for supplied values and implementations
  • .mock().impl() for flexible implementations

Both configurations inject a dependency into the unit, but only .impl() creates a mock available through unitRef.get(). See injected dependencies and retrievable mocks for the relationship.

InjectableIdentifier<D> from @suites/types.di includes classes, strings, symbols, and adapter-registered tokens such as InjectionJS’s InjectionToken<D>. The signatures below summarize the overloads; load your adapter declarations to enable its token types.

Methods

.mock().final()

Injects your supplied value without turning it into a configurable mock. It cannot be retrieved through unitRef; this does not freeze the JavaScript object. Use .final() for:

  • Fixed behavior that won’t change across tests
  • Configuration objects and primitives (non-class tokens)
  • Values that don’t need runtime control or verification

Signature

mock<D>(dependency: InjectableIdentifier<D>)
.final(implementation: DeepPartial<D>): TestBuilder

Parameters

ParameterTypeDescription
dependencyInjectableIdentifier<D>The dependency to mock
implementationDeepPartial<D>Object with method implementations

Example

For class-based tokens (fixed behavior):

const { unit } = await TestBed.solitary(UserService)
.mock(UserApi)
.final({
getRandom: async () => ({ id: 1, name: "John" }),
getAll: async () => [{ id: 1, name: "John" }]
})
.compile();
// UserApi cannot be retrieved - behavior is fixed

For configuration objects and primitives:

const { unit } = await TestBed.solitary(PaymentService)
.mock<DatabaseConfig>('DATABASE_CONFIG')
.final({ host: 'localhost', port: 5432 })
.mock<string>('API_KEY')
.final('test-api-key-12345')
.compile();
// Config values are injected but not retrievable

.mock().impl()

Creates a flexible mock configuration using the installed doubles adapter. The stubFn callback creates a Jest or Vitest mock function.

Signature

mock<D>(dependency: InjectableIdentifier<D>)
.impl(factory: (stubFn: () => MockFunction) => DeepPartial<D>): TestBuilder

Parameters

ParameterTypeDescription
dependencyInjectableIdentifier<D>The dependency to mock
factory(stubFn) => DeepPartial<D>Factory function receiving the mock library’s stub function

Example

const { unit, unitRef } = await TestBed.solitary(UserService)
.mock(UserApi)
.impl(stubFn => ({
getRandom: stubFn().mockResolvedValue({ id: 1, name: "John" }),
getAll: stubFn().mockReturnValue([])
}))
.compile();
// UserApi can still be retrieved and modified
const userApi = unitRef.get(UserApi);
userApi.getRandom.mockResolvedValue({ id: 2, name: "Jane" });

InjectionJS tokens

With @suites/di.injectionjs/metadata referenced, use the same InjectionToken instance as your constructor. This example uses the service and token from the InjectionJS guide:

import { TestBed } from '@suites/unit';
import { USER_REPOSITORY, UserService } from './user.service';
import type { UserRepository } from './user.service';
const { unit, unitRef } = await TestBed.solitary(UserService)
.mock<UserRepository>(USER_REPOSITORY)
.impl(stub => ({ findName: stub().mockResolvedValue('Alice') }))
.compile();
const repository = unitRef.get<UserRepository>(USER_REPOSITORY);

You can also use .final(...) to supply a value. Omit the metadata argument for InjectionJS. Token descriptions are labels, not identifiers: separate token instances stay distinct even when their descriptions match.

Inversify metadata

With @suites/di.inversify/metadata referenced, pass named or tagged metadata as the second argument: .mock(Repository, { named: 'primary' }). Retrieve it using the same metadata in unitRef.get(). With @suites/di.nestjs/metadata, omit this argument; NestJS identifies dependencies by class or token alone.

Example

Multiple Mock Configurations

You can chain multiple mock configurations:

const { unit, unitRef } = await TestBed.solitary(OrderService)
.mock(Database)
.final({
getOrder: async (id: string) => ({ id, items: [] })
})
.mock(EmailService)
.impl(stubFn => ({
send: stubFn().mockResolvedValue({ sent: true })
}))
.compile();
// Can retrieve EmailService and Logger, but not Database
const emailService = unitRef.get(EmailService);
const logger = unitRef.get(Logger);

See Also