0Pricing
Angular Academy · Урок

Имитация сервисов и зависимостей

Предоставляйте тестовые двойники через DI

«Имитация сервисов и зависимостей» — бесплатный урок Angular Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Angular Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Angular Academy содержит 4 уроков всего.

Зачем имитировать зависимости

Тест компонента должен проверять компонент изолированно. Если он внедряет службу на основе HttpClient, реальные сетевые запросы не нужны. Вместо этого предоставьте тестовую замену — поддельный объект, возвращающий контролируемые данные, чтобы тесты были быстрыми и предсказуемыми.

Предоставление подделки через useValue

Самая простая тестовая замена — обычный объект, переданный через useValue. Предоставьте его под тем же токеном внедрения, который запрашивает компонент.

const fakeApi = { getUser: () => of({ name: 'Ada' }) };
TestBed.configureTestingModule({
  imports: [ProfileComponent],
  providers: [{ provide: UserApi, useValue: fakeApi }],
});

Шпионы Jasmine

jasmine.createSpyObj создаёт подделку с методами-шпионами, поэтому можно и задавать возвращаемые значения, и проверять вызовы.

const apiSpy = jasmine.createSpyObj<UserApi>('UserApi', ['getUser']);
apiSpy.getUser.and.returnValue(of({ name: 'Ada' }));
TestBed.configureTestingModule({
  providers: [{ provide: UserApi, useValue: apiSpy }],
});

Проверка вызова службы

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

fixture.componentInstance.load(7);
fixture.detectChanges();
expect(apiSpy.getUser).toHaveBeenCalledWith(7);
expect(apiSpy.getUser).toHaveBeenCalledTimes(1);

Возврат наблюдаемых объектов из подделок

Службы часто возвращают наблюдаемые объекты. Используйте RxJS of() для синхронного успешного результата и throwError() для ошибок, чтобы проверить обе ветви.

import { of, throwError } from 'rxjs';

apiSpy.getUser.and.returnValue(of({ name: 'Ada' }));     // success
apiSpy.getUser.and.returnValue(throwError(() => new Error('boom'))); // error

useClass для повторно используемых подделок

Если подделка используется во многих спецификациях, определите класс и подключите его через useClass.

class FakeUserApi {
  getUser() { return of({ name: 'Test' }); }
}
TestBed.configureTestingModule({
  providers: [{ provide: UserApi, useClass: FakeUserApi }],
});

Имитация HttpClient с помощью HttpTestingController

Чтобы тестировать службы, которые выполняют HTTP-вызовы, не подменяя всю службу целиком, импортируйте provideHttpClientTesting() и очищайте запросы через HttpTestingController.

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

TestBed.configureTestingModule({
  providers: [provideHttpClient(), provideHttpClientTesting()],
});

Очистка HTTP-запроса

Ожидайте запрос, ответьте на него тестовыми данными, а затем убедитесь, что непредвиденных вызовов не осталось.

const http = TestBed.inject(HttpTestingController);
service.load();
const req = http.expectOne('/api/users/7');
expect(req.request.method).toBe('GET');
req.flush({ name: 'Ada' });
http.verify();

Переопределение поставщика для отдельного теста

Иногда одному тесту нужна другая подмена. Используйте TestBed.overrideProvider() перед createComponent.

TestBed.overrideProvider(UserApi, {
  useValue: { getUser: () => throwError(() => new Error('fail')) },
});
const fixture = TestBed.createComponent(ProfileComponent);

Подменяйте только необходимое

Хорошая тестовая замена реализует только те методы, которые фактически использует компонент. Чрезмерная подмена связывает тест с внутренним устройством, а недостаточная позволяет реальным побочным эффектам просачиваться наружу. Ориентируйтесь на открытый контракт, от которого зависит компонент.

Шпионинг за методами реальной службы

Можно также оставить реальную службу, но установить шпиона на один метод с помощью spyOn(instance, 'method'). Это полезно, когда большая часть службы безвредна, но один вызов нужно перехватить.

const svc = TestBed.inject(AnalyticsService);
spyOn(svc, 'track');
fixture.componentInstance.onClick();
expect(svc.track).toHaveBeenCalledWith('click');

Быстрая проверка

Как с помощью подмены проверять вызовы и одновременно управлять возвращаемыми значениями?

Итоги

Вы заменяли реальные зависимости тестовыми заменами с помощью useValue, useClass и шпионов Jasmine; возвращали Observable с помощью of/throwError; тестировали HTTP через HttpTestingController; а также переопределяли поставщиков для отдельных тестов. Подменяйте только тот контракт, который использует компонент.

Часто задаваемые вопросы

Урок «Имитация сервисов и зависимостей» бесплатный?

Да — полный текст урока «Имитация сервисов и зависимостей» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Angular Academy, подпишись на CoddyKit PRO. Курс Angular Academy содержит 4 уроков всего.

Чему я научусь в уроке «Имитация сервисов и зависимостей»?

Предоставляйте тестовые двойники через DI Ты практикуешь Angular Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Angular Academy?

Предыдущий опыт не требуется. Angular Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Имитация сервисов и зависимостей»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Angular Academy?

Да. Каждый урок Angular Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. TestBed и приспособления компонентов
  2. Тестирование входных данных, выходных данных и DOM
  3. Имитация сервисов и зависимостей
  4. Тестирование сигналов и асинхронного кода
← Назад к Angular Academy