Skip to content

Тестирование

Используйте .override(), когда тестам нужно заменить существующую регистрацию на мок.

ts
function buildContainer() {
  return new Container()
    .registerClass('logger', ConsoleLogger, [])
    .registerClass('db', PgDb, [])
    .registerClass('users', UserRepo, ['logger', 'db'])
}

const c = buildContainer()
  .override('logger', mockLogger)
  .override('db', mockDb)

Значение override должно быть совместимо с исходным зарегистрированным типом. Отсутствующие ключи и несовместимые моки дают ошибки TypeScript.

Когда делать override

Применяйте overrides до разрешения графа зависимостей:

ts
const logger = c.get('logger')
c.override('logger', mockLogger)

Вторая строка бросит ошибку, потому что singleton уже находится в локальном кеше контейнера. Проверка намеренно опирается только на кеш: она также обнаруживает scoped-значения в текущем scope, registerValue и повторный override. Transient-значения и значения предка, разрешённые через дочерний контейнер, локально не кешируются, поэтому проверка их не видит. Уже выданный transient остаётся у вызывающего кода, а последующие resolve возвращают мок. Это часть контракта, а не разрешение на поздние overrides: применяйте их до разрешения графа, чтобы не расколоть его.

Владение

Override-значения принадлежат внешнему коду. Как и registerValue, override не добавляется в очередь dispose контейнера. Очистка остаётся за тестовой фикстурой.

Локальность scope

Override меняет только контейнер, на котором вызван:

ts
const scope = root.createScope().override('db', mockDb)

Корневой контейнер и соседние scopes не меняются. Overrides на уровне родителя видны через обычный поиск в родительском контейнере.