Тесты читаются
В коде теста остаются только поля, которые он проверяет. Остальные поля заполняются значениями по умолчанию.
Хелперы собирают корректный объект целиком — в тесте вы указываете только важные для него поля
Тестируемый код обращается за данными наружу — например, веб-приложение запрашивает сервер. В тестах эти ответы подменяют заглушками, и заглушки быстро разрастаются: чтобы объект был корректным, приходится заполнять десятки полей, из которых тесту важны два-три. Код теста тонет в неважных деталях, а при изменении типов заглушки рассыпаются по всему проекту.
ts-stub-gen решает это генерацией: для каждого типа создаётся функция, возвращающая объект со значениями по умолчанию. Параметр overrides принимает только те поля, которые нужны тесту:
// вручную: что здесь проверяется?
const response: Response = {
requestId: "r-1",
status: "ok",
pagination: { page: 1, perPage: 20, total: 1 },
account: { id: "42", balance: 0, tags: [], createdAt: new Date(0) },
};
// с ts-stub-gen: тест проверяет счёт с id "42" — это и видно
const response = GetStubResponse({
account: GetStubAccount({ id: "42" }),
});Хелперы компонуются: для вложенного поля передаётся результат хелпера вложенного типа. Так собираются сложные иерархии данных без единого лишнего поля в коде теста.
ts-stub-gen работает с типами, которые описывают данные без поведения: интерфейсами, алиасами типов и enum. Хелперы генерируются для всех экспортированных типов из entry; типы, на которые они ссылаются, подхватываются автоматически — в том числе из других файлов, через реэкспорты и переименованные импорты. Неэкспортированные типы раскрываются прямо внутри стаба.
Всё, что умеет вычислять компилятор TypeScript, раскрывается на этапе генерации:
Paginated<Account> превращается в конкретную структуру;Partial, Pick, Omit, Required, Readonly, ReturnType, NonNullable и другие;A & B, mapped types и indexed access (Settings['a']);z.infer (zod), v.InferOutput (valibot), t.TypeOf (io-ts) и аналогичные.Последний пункт означает, что типы не обязательно описывать вручную — если они выводятся из схем валидации, стабы сгенерируются точно так же.
Конструкции, которые нельзя превратить в данные, получают значение undefined as any и сопровождаются предупреждением — уровни настраиваются в секции warnings:
behavior-in-type;Map, Set, Promise — предупреждение unsupported-type;export default, пропускается — предупреждение default-export;A.B.C) пока не поддерживается.Enum, участвующий в типах данных, должен быть экспортирован: иначе сгенерированному коду неоткуда его импортировать, и генерация завершается ошибкой enum-not-exported.
Отдельное ограничение связано с рекурсией: тип с обязательным полем, ссылающимся на самого себя (next: LinkedList), невозможно представить конечным объектом, поэтому вызов такого хелпера приведёт к бесконечной рекурсии в рантайме. Рекурсия через массив (children: Tree[]) или опциональное поле работает нормально.
Поля типа Date получают значение new Date(0). Если ваша команда не допускает Date в данных — например, ради JSON-сериализуемости, — включите предупреждение date-type в уровень warn или error.