Хуки: beforeEach, afterEach, beforeAll, afterAll

Урок объясняет хуки жизненного цикла, которые готовят и убирают состояние вокруг тестов.

Хук — функция, которую Jest вызывает автоматически до или после тестов, чтобы подготовить или очистить окружение.

Зачем хуки

Часто перед каждым тестом нужно одно и то же: создать свежий объект, очистить базу, сбросить счётчик. Дублировать это в каждом it — плохо. Хуки выносят повторяющуюся подготовку в одно место.

Четыре хука

ХукКогда вызывается
beforeAllодин раз перед всеми тестами блока
beforeEachперед каждым тестом
afterEachпосле каждого теста
afterAllодин раз после всех тестов блока

Типичный пример

describe('Корзина', () => {
  let cart;

  beforeEach(() => {
    cart = new Cart(); // свежая корзина перед КАЖДЫМ тестом
  });

  it('пустая корзина стоит 0', () => {
    expect(cart.total()).toBe(0);
  });

  it('добавление товара увеличивает сумму', () => {
    cart.add({ price: 100 });
    expect(cart.total()).toBe(100);
  });
});

Благодаря beforeEach второй тест не видит изменений первого: каждый стартует с чистой корзиной.

Порядок выполнения

Проиллюстрируем порядок вызова хуков живым логом:

const log = [];

function beforeAll(fn) { fn('beforeAll'); }
function runTest(name, before, after, test) {
  before('beforeEach');
  test(name);
  after('afterEach');
}

beforeAll(label => log.push(label));
['тест A', 'тест B'].forEach(name => {
  runTest(name,
    label => log.push(label),
    label => log.push(label),
    n => log.push('  ' + n));
});
log.push('afterAll');

console.log(log.join('\n'));

Вывод:

beforeAll
beforeEach
  тест A
afterEach
beforeEach
  тест B
afterEach
afterAll

Видно: beforeAll и afterAll срабатывают по одному разу на краях, а beforeEach/afterEach оборачивают каждый тест.

beforeAll против beforeEach

beforeEach — для свежего состояния под каждый тест (изоляция). beforeAll — для дорогой одноразовой подготовки, которую не нужно повторять (например, поднять тестовый сервер). Очистку в afterEach/afterAll делают, чтобы один тест не «протекал» в другой.

Итог

  • Хуки выносят повторяющуюся подготовку/очистку из тестов.
  • beforeEach/afterEach — вокруг каждого теста; beforeAll/afterAll — один раз на блок.
  • beforeEach обеспечивает свежее состояние и изоляцию.
  • Дорогую одноразовую подготовку выносят в beforeAll.
Проверьте себя
1. Когда вызывается хук beforeEach?
AОдин раз перед всеми тестами
BПеред каждым тестом блока
CПосле всех тестов
DТолько при провале теста
2. Для чего обычно используют beforeAll вместо beforeEach?
AЧтобы тест падал быстрее
BДля дорогой одноразовой подготовки, которую не нужно повторять перед каждым тестом
CЧтобы отключить тесты
DbeforeAll и beforeEach идентичны
3. Зачем нужны хуки afterEach/afterAll?
AЧтобы ускорить expect
BЧтобы очищать состояние и не дать одному тесту повлиять на другой
CЧтобы создавать новые тесты
DОни обязательны в каждом тесте
Поддержать проект