Код-ревью Middle Jest и Vitest обновлено

Ревью: unit-тесты на Jest

Вопрос

Найдите проблемы в тестах сервиса уведомлений.

import { notify } from './notify';
import * as mailer from './mailer';

describe('notify', () => {
  const send = jest.spyOn(mailer, 'send');

  it('отправляет письмо', () => {
    notify({ email: 'a@b.ru' });
    expect(send).toBeCalled();
  });

  it('повторяет при ошибке', async () => {
    send.mockRejectedValueOnce(new Error('smtp'));
    notify({ email: 'a@b.ru' });
    await new Promise((r) => setTimeout(r, 1000));
    expect(send.mock.calls.length).toBe(2);
  });

  it('формирует тему', () => {
    expect(buildSubject('order', { id: 5 })).toMatchSnapshot();
  });
});

Коротко

Нужно: jest.restoreAllMocks() или restoreMocks: true, шпион в beforeEach, await notify(...), фейковые таймеры для ретрая, проверки toHaveBeenCalledWith с аргументами и toHaveBeenCalledTimes, явная ожидаемая строка темы.

Что должен найти ревьюер

  1. Ошибкастрока 5
    Шпион создаётся один раз на describe и не сбрасывается: счётчик вызовов копится между тестами
  2. Ошибкастрока 8
    Асинхронный notify без await: проверка может выполниться до отправки
  3. Стильстрока 9
    Проверка только факта вызова, без аргументов (адрес, тема)
  4. Производительностьстрока 15
    Реальное ожидание 1 секунду вместо фейковых таймеров
  5. Ошибкастрока 16
    Счётчик 2 зависит от вызова в предыдущем тесте, без сброса шпиона тест ложный
  6. Ошибкастрока 20
    buildSubject не импортирован, а снапшот для короткой строки хуже явного toBe

Разбор

Нужно: jest.restoreAllMocks() или restoreMocks: true, шпион в beforeEach, await notify(...), фейковые таймеры для ретрая, проверки toHaveBeenCalledWith с аргументами и toHaveBeenCalledTimes, явная ожидаемая строка темы.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.