Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: unit testing, mock, spy, method call verification, test assertions

Почему важно проверять количество вызовов метода, а не только факт вызова?

Этот вопрос проверяет понимание разницы между проверкой факта вызова метода и проверкой точного количества его вызовов, что важно для тестирования побочных эффектов и корректности логики.

Короткий ответ

Проверка количества вызовов метода важна, потому что она гарантирует, что логика программы работает корректно, а не просто срабатывает. Например, метод отправки уведомления должен вызываться ровно один раз, а не ноль или два. Проверка только факта вызова может пропустить ошибки, такие как лишние вызовы в цикле или пропущенные вызовы из-за условия. Это помогает избежать багов, связанных с производительностью или побочными эффектами.

Длинный ответ

В модульном тестировании часто используется мокирование (mock) или шпионаж (spy) для проверки взаимодействия с внешними зависимостями. Проверка, что метод был вызван, подтверждает, что определённый путь кода был выполнен. Однако этого недостаточно для полноценной проверки корректности логики.

Почему количество вызовов имеет значение

Рассмотрим типичный сценарий: метод, который отправляет email пользователю. Если мы проверяем только факт вызова, тест пройдёт, даже если метод был вызван дважды (что приведёт к дублированию писем) или не был вызван вовсе из-за ошибки в условии. Проверка точного количества вызовов (например, ровно один раз) гарантирует, что побочный эффект произошёл ожидаемое число раз.

Примеры проблем при отсутствии проверки

  • Лишние вызовы в цикле: Ошибка в условии может привести к вызову метода для каждого элемента массива, хотя должен быть один вызов для всего блока.
  • Пропущенные вызовы: Метод может не вызываться из-за преждевременного возврата (return) или неверной логики ветвления.
  • Производительность: Лишние вызовы к API, базе данных или дорогостоящим операциям замедляют работу приложения.

Пример кода с тестом

Допустим, у нас есть сервис уведомлений, который должен отправлять приветственное письмо новому пользователю, но только если пользователь активировал эту опцию.

class UserService {
  constructor(notifier) {
    this.notifier = notifier;
  }

  registerUser(user, sendWelcomeEmail) {
    // Регистрация пользователя в системе...
    if (sendWelcomeEmail) {
      this.notifier.sendWelcomeEmail(user.email);
    }
  }
}

// Тест с использованием Jest и моков
it('should send welcome email exactly once when flag is true', () => {
  const mockNotifier = {
    sendWelcomeEmail: jest.fn()
  };
  const service = new UserService(mockNotifier);
  const testUser = { email: 'test@example.com' };

  service.registerUser(testUser, true);

  // Проверка только факта вызова:
  // expect(mockNotifier.sendWelcomeEmail).toHaveBeenCalled();
  // Этого недостаточно!

  // Правильная проверка количества вызовов:
  expect(mockNotifier.sendWelcomeEmail).toHaveBeenCalledTimes(1);
  expect(mockNotifier.sendWelcomeEmail).toHaveBeenCalledWith('test@example.com');
});

it('should not send email when flag is false', () => {
  const mockNotifier = {
    sendWelcomeEmail: jest.fn()
  };
  const service = new UserService(mockNotifier);
  const testUser = { email: 'test@example.com' };

  service.registerUser(testUser, false);

  // Проверка, что метод не вызывался ни разу:
  expect(mockNotifier.sendWelcomeEmail).toHaveBeenCalledTimes(0);
});

Где это применяется

Такая практика широко используется в модульном и интеграционном тестировании, особенно при работе с:

  • Внешними API (платёжные шлюзы, почтовые сервисы).
  • Базами данных (проверка количества запросов INSERT/UPDATE).
  • Логированием (убедиться, что ошибка залогирована определённое число раз).
  • Кэшированием (проверка, что дорогой метод вызван один раз, а результат закэширован).

Вывод: Проверка количества вызовов метода — это важная практика для написания надёжных тестов. Она позволяет убедиться не только в том, что код был выполнен, но и в том, что он выполнился корректное количество раз, предотвращая ошибки логики и неэффективное использование ресурсов. Особенно критична эта проверка для методов с побочными эффектами (отправка данных, изменение состояния).

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    3

Навыки

  • JavaScript

    JavaScript

  • Testing

Ключевые слова

#unit testing

#mock

#spy

#method call verification

#test assertions

Подпишись на iOS Developer в телеграм

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.