Мокирование зависимостей

Мокирование зависимостей в Angular играет ключевую роль при написании модульных тестов. Оно позволяет изолировать тестируемый компонент или сервис от внешних зависимостей, таких как HTTP-запросы, сервисы или хранилища состояния.

Создание моков для сервисов

Для мокирования сервисов обычно создают объекты с тем же интерфейсом, что и реальный сервис, но с упрощенной или предопределенной логикой.

class MockUserService {
  getUser() {
    return of({ id: 1, name: 'Test User' });
  }
}

Использование моков в тестах компонентов:

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [UserComponent],
    providers: [
      { provide: UserService, useClass: MockUserService }
    ]
  }).compileComponents();
});

Мокирование HTTP-запросов

Angular предоставляет HttpClientTestingModule и HttpTestingController для имитации HTTP-запросов:

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [HttpClientTestingModule],
    providers: [DataService]
  });

  service = TestBed.inject(DataService);
  httpMock = TestBed.inject(HttpTestingController);
});

it('должен получить данные', () => {
  service.getData().subscribe(data => {
    expect(data).toEqual(mockData);
  });

  const req = httpMock.expectOne('api/data');
  expect(req.request.method).toBe('GET');
  req.flush(mockData);
});

HttpTestingController позволяет проверять, какие запросы были отправлены, и управлять их результатами, что делает тесты детерминированными и независимыми от внешней среды.

Использование спаев (spy)

Спаи позволяют контролировать вызовы методов существующих объектов без необходимости создавать полностью отдельный мок:

const userServiceSpy = jasmine.createSpyObj('UserService', ['getUser']);
userServiceSpy.getUser.and.returnValue(of({ id: 1, name: 'Spy User' }));

TestBed.configureTestingModule({
  providers: [
    { provide: UserService, useValue: userServiceSpy }
  ]
});

Спаи удобны, когда нужно проверять количество вызовов, передаваемые параметры и возвращаемые значения метода.

Рекомендации по структурированию моков

  • Создавать отдельные файлы для сложных моков, чтобы поддерживать чистоту тестового кода.
  • Использовать фабрики моков для генерации разных сценариев поведения.
  • Сочетать мокирование с асинхронными утилитами fakeAsync и tick для тестирования таймеров и задержек.

Мокирование зависимостей позволяет сделать тесты предсказуемыми, уменьшить время их выполнения и сосредоточиться на логике тестируемого компонента или сервиса.