Jest: describe, it, expect

Три базовых строительных блока Jest: describe группирует тесты, it/test объявляет один тест, expect — формулирует утверждение о результате.

Зачем нужно

Без структуры тесты превращаются в набор разрозненных функций без контекста. describe даёт иерархию, it — читаемое намерение («it should do X»), expect — конкретное утверждение. Вместе они формируют самодокументирующийся тест-сьют.

Где используется

  • Любые unit и integration тесты в проектах с Jest или Vitest
  • BDD-стиль описания поведения компонентов и функций
  • Отчёты в CI: Jest выводит иерархию describe → it в консоль

Основной контент

Базовая структура

// sum.test.js
import { sum } from './sum';

describe('sum', () => {
  it('складывает два положительных числа', () => {
    expect(sum(2, 3)).toBe(5);
  });

  it('работает с нулём', () => {
    expect(sum(0, 5)).toBe(5);
  });

  it('работает с отрицательными числами', () => {
    expect(sum(-1, -2)).toBe(-3);
  });
});

test vs it

test и it — синонимы. it читается как «оно должно...», test — нейтральное. Выбери один стиль и придерживайся его в проекте.

test('возвращает true для чётного числа', () => { /* ... */ });
it('returns true for even number', () => { /* ... */ });

Основные матчеры expect

expect(value).toBe(5);              // строгое равенство (===)
expect(value).toEqual({ a: 1 });    // глубокое равенство объектов
expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(value).toBeNull();
expect(value).toBeUndefined();
expect(value).toContain('item');    // массивы и строки
expect(value).toHaveLength(3);
expect(value).toBeGreaterThan(0);
expect(fn).toThrow('error message');
expect(fn).toThrowError(TypeError);

Вложенные describe

describe('UserService', () => {
  describe('getUser', () => {
    it('возвращает пользователя по id', () => { /* ... */ });
    it('выбрасывает ошибку если не найден', () => { /* ... */ });
  });

  describe('createUser', () => {
    it('создаёт пользователя с валидными данными', () => { /* ... */ });
  });
});

Модификаторы: skip и only

describe.skip('пропускаем весь блок', () => { /* ... */ });
it.only('запускаем только этот тест', () => { /* ... */ });
// Внимание: .only в коммите сломает CI!

Негативные утверждения

expect(value).not.toBe(null);
expect(arr).not.toContain('forbidden');

Частые ошибки

  • toBe для объектов — сравнивает по ссылке, а не по значению; используй toEqual
  • it.only попал в коммит — CI будет запускать только один тест и формально «проходить»
  • Слишком широкое describe — один блок покрывает несколько несвязанных функций; дели по ответственностям
  • Пустое it без expect — тест проходит, но ничего не проверяет; добавь expect.assertions(1) чтобы это поймать

Связанные темы

Ресурсы