TestBed и утилиты тестирования

Angular предоставляет встроенный инструмент для модульного тестирования компонентов и сервисов — TestBed. Он позволяет создавать тестовые окружения, имитировать работу зависимостей и проверять корректность поведения приложения без запуска всей инфраструктуры.

Настройка TestBed

Для начала создаётся тестовый модуль с помощью TestBed.configureTestingModule:

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [MyComponent],
    imports: [HttpClientTestingModule, ReactiveFormsModule],
    providers: [MyService]
  }).compileComponents();
});

Особенности:

  • declarations — компоненты, директивы, пайпы, которые будут использоваться в тестах.
  • imports — модули, необходимые для работы компонентов (формы, HTTP-тестирование и т.д.).
  • providers — сервисы, которые нужно внедрить в тестируемый компонент.

Создание экземпляра компонента

После конфигурации модуля создаётся экземпляр компонента и его фикстура:

let fixture: ComponentFixture<MyComponent>;
let component: MyComponent;

beforeEach(() => {
  fixture = TestBed.createComponent(MyComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});
  • fixture позволяет управлять жизненным циклом компонента и получать доступ к DOM.
  • detectChanges() запускает привязку данных и инициализацию компонентов.

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

Angular поддерживает замену реальных сервисов на заглушки или spy-объекты:

const myServiceSpy = jasmine.createSpyObj('MyService', ['getData']);
myServiceSpy.getData.and.returnValue(of([1, 2, 3]));

TestBed.overrideProvider(MyService, { useValue: myServiceSpy });

Это позволяет тестировать компонент изолированно, проверяя только его поведение.

Утилиты тестирования

  • async() и waitForAsync() — оборачивают асинхронные операции для корректной работы с fixture.detectChanges().
  • fakeAsync() и tick() — эмулируют таймеры и асинхронные задачи, полезны для тестирования задержек и анимаций.
  • flush() — очищает все отложенные задачи и таймеры, завершая текущий цикл обработки.

Пример проверки асинхронного метода:

it('should load data', fakeAsync(() => {
  component.loadData();
  tick(500);
  expect(component.items.length).toBe(3);
}));

Доступ к DOM и проверка элементов

fixture.nativeElement и fixture.debugElement позволяют проверять состояние DOM и взаимодействовать с элементами:

const button = fixture.debugElement.query(By.css('button'));
button.triggerEventHandler('click', null);
fixture.detectChanges();
expect(component.isClicked).toBeTrue();

Использование By.css() обеспечивает гибкость поиска элементов, а triggerEventHandler позволяет эмулировать события без реального взаимодействия пользователя.

Angular TestBed и встроенные утилиты предоставляют полный инструментарий для надёжного, модульного и интеграционного тестирования, обеспечивая стабильность приложения при изменениях и масштабировании.