Что такое Test Doubles (Mock, Spy, Stub)?angular-100

Test Doubles — это общее название для объектов-заменителей, используемых в тестировании вместо реальных зависимостей. Они помогают изолировать тестируемый код и контролировать поведение зависимостей. В Angular-тестировании чаще всего применяются три основных типа:

1. Mock

Мок — полностью фейковый объект с предопределённым поведением.

// Пример мока сервиса
const authServiceMock = {
  isAuthenticated: jasmine.createSpy('isAuthenticated').and.returnValue(true),
  login: jasmine.createSpy('login').and.returnValue(of({ success: true }))
};

TestBed.configureTestingModule({
  providers: [
    { provide: AuthService, useValue: authServiceMock }
  ]
});

Когда использовать:

  • Когда нужно полностью заменить сложную зависимость
  • Когда важно проверить, был ли вызван метод с правильными аргументами

2. Spy

Spy — обёртка вокруг реального объекта, позволяющая отслеживать вызовы методов без изменения их поведения (или с частичной подменой).

// Пример использования spyOn
const realService = TestBed.inject(DataService);
spyOn(realService, 'fetchData').and.callThrough(); // Реальный метод
spyOn(realService, 'saveData').and.returnValue(of(null)); // Подмена

Когда использовать:

  • Когда нужно частично замокать объект
  • Когда важно сохранить оригинальное поведение некоторых методов
  • Для отслеживания вызовов существующих методов

3. Stub

Stub — упрощённая реализация зависимости с жёстко заданными возвращаемыми значениями.

// Пример стаба
class LoggerStub {
  log(message: string) {
    return '[STUBBED]: ' + message;
  }
}

TestBed.configureTestingModule({
  providers: [
    { provide: LoggerService, useClass: LoggerStub }
  ]
});

Когда использовать:

  • Для замены сложных зависимостей простыми реализациями
  • Когда нужно эмулировать конкретные сценарии работы
  • Для тестирования edge-cases (ошибок, предельных значений)

Сравнительная таблица

Характеристика Mock Spy Stub
Реальная логика ❌ Нет ✅ Частично ❌ Нет
Подмена возврата ✅ Да ✅ Да ✅ Да
Отслеживание вызовов ✅ Да ✅ Да ❌ Нет
Сложность создания ⚠️ Средняя ✅ Низкая ⚠️ Средняя

Практические примеры в Angular

Mock HTTP-запросов

const httpMock = {
  get: jasmine.createSpy('get').and.returnValue(of(mockData))
};

// В тесте:
expect(httpMock.get).toHaveBeenCalledWith('/api/data');

Spy на компоненте

const component = fixture.componentInstance;
spyOn(component, 'onSubmit').and.callThrough();

// После действия:
expect(component.onSubmit).toHaveBeenCalled();

Stub для роутера

const routerStub = {
  navigate: jasmine.createSpy('navigate')
};

// Проверка:
expect(routerStub.navigate).toHaveBeenCalledWith(['/login']);

Резюмируем

Test Doubles — важнейший инструмент для изолированного тестирования. Mocks лучше для полной подмены, Spies — для отслеживания вызовов реальных методов, Stubs — для простых предсказуемых реализаций. В Angular-тестах чаще всего используются комбинации этих подходов через TestBed и Jasmine spies.