В системе валидации Vest хуки before и
after используются для управления жизненным циклом
выполнения правил внутри сьютов. Они позволяют выполнять побочные
эффекты, подготовительные действия и постобработку, не смешивая их с
логикой самих проверок. Такой подход делает валидационные сценарии более
предсказуемыми и композиционно чистыми.
Сьют в Vest представляет собой функцию, внутри которой описываются правила валидации. При каждом запуске сьюта создаётся контекст выполнения, в рамках которого последовательно вызываются зарегистрированные правила и хуки.
Упрощённая последовательность выглядит следующим образом:
before хуковafter хуковКлючевая особенность заключается в том, что хуки не влияют напрямую на результат валидации, но могут изменять окружение, в котором эти результаты формируются.
Хук before выполняется до запуска основной логики сьюта.
Он предназначен для подготовки данных, инициализации состояния,
установки внешних зависимостей или конфигурации, необходимой для
корректного выполнения правил.
Хук может быть синхронным или асинхронным, что позволяет использовать его для работы с внешними источниками данных.
Инициализация состояния
Перед выполнением правил часто требуется подготовить промежуточные данные:
Загрузка внешних данных
Если валидация зависит от серверных данных:
Подготовка контекста
Хук может модифицировать контекст выполнения:
import { suite, test, before } from 'vest';
const validateUser = suite('user_validation', (data) => {
before(async () => {
data.normalizedEmail = data.email?.trim().toLowerCase();
});
test('email', 'invalid email format', () => {
expect(data.normalizedEmail).toMatch(/.+@.+\..+/);
});
});
В данном случае before выполняет нормализацию email
перед запуском проверок, гарантируя единообразие данных.
Асинхронный вариант позволяет выполнять операции, требующие ожидания:
before(async () => {
const response = await fetchUserSettings();
data.settings = await response.json();
});
Особенность заключается в том, что выполнение сьюта будет
приостановлено до завершения before, что гарантирует
консистентность состояния для последующих тестов.
before всегда выполняется один раз на запуск сьюта,
независимо от количества правил внутри. Это делает его эквивалентом
глобальной инициализации для конкретного сценария валидации.
Хук after выполняется после завершения всех правил и
групп внутри сьюта. Он используется для очистки ресурсов, логирования,
побочных эффектов и финальной обработки результатов.
В отличие от before, after не влияет на
выполнение правил, так как к моменту его вызова результат уже
сформирован.
Логирование результатов
После завершения валидации можно отправить результаты в систему мониторинга:
Очистка ресурсов
Если в before были открыты внешние ресурсы:
Постобработка результатов
Иногда требуется агрегировать данные:
import { suite, test, after } from 'vest';
const validateProfile = suite('profile_validation', (data) => {
test('username', 'required field', () => {
expect(data.username).toBeTruthy();
});
after((results) => {
console.log('validation finished:', results);
});
});
Здесь after получает итоговый объект результатов,
позволяя анализировать итог выполнения всех тестов.
Как и before, after поддерживает
асинхронность:
after(async (results) => {
await sendMetrics(results);
});
Асинхронный after не влияет на возвращаемый результат
сьюта, но позволяет гарантировать выполнение побочных операций до
завершения процесса.
В рамках одного сьюта может быть несколько хуков before
и after. Их порядок выполнения строго фиксирован.
Все before хуки выполняются последовательно в порядке
объявления:
before(() => {
data.step = 1;
});
before(() => {
data.step = 2;
});
Итоговое значение будет зависеть от последовательного изменения состояния.
after хуки выполняются также в порядке регистрации, но
уже после завершения всех правил:
after(() => {
console.log('first');
});
after(() => {
console.log('second');
});
И before, и after имеют доступ к контексту
выполнения сьюта. Однако характер доступа различается:
before — модифицирует входные данные до начала
проверокafter — работает с уже сформированным результатомVest обеспечивает изолированное выполнение сьютов. Это означает, что
изменения, внесённые в before, не протекают между
различными вызовами одного и того же сьюта.
При наличии асинхронных хуков полный цикл выполнения приобретает следующую структуру:
before (ожидание завершения)after (с ожиданием завершения)Такая модель обеспечивает предсказуемость даже при наличии сетевых запросов и внешних зависимостей.
Частая ошибка — выполнение подготовительных операций внутри тестов, что приводит к дублированию логики и усложнению сопровождения.
Попытка модифицировать результат в after не влияет на
возвращаемое значение сьюта, так как результат уже сформирован к моменту
вызова.
Если before или after не возвращают
корректный промис, возможны гонки данных или неполная инициализация
контекста.
Механизм before и after формирует слой
управления жизненным циклом, отделяя бизнес-логику валидации от
инфраструктурных задач. Это позволяет:
Такой подход делает сьюты более декларативными и устойчивыми к росту сложности логики.