Frontend
October 15, 2023

Тестирование компонентов в Angular с TestBed

Почему тестирование компонентов важно в Angular

Тестирование компонентов в Angular дает несколько преимуществ:

  • Улучшает качество кода. Тесты помогают найти и исправить ошибки в коде компонентов.
  • Делает код более надежным. Хорошее покрытие тестами снижает вероятность появления новых ошибок при изменении кода.
  • Упрощает добавление новой функциональности. Наличие тестов позволяет не бояться ломать существующий код.
  • Ускоряет разработку. Тесты значительно уменьшают время на отладку кода.

Короче, если писать тесты для компонентов в Angular, то разработка будет идти быстрее, а результат получится более качественным.

Основы тестирования компонентов с использованием TestBed

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

Чтобы начать, нужно импортировать TestBed и связанные с ним API из @angular/core/testing:

import {TestBed} from '@angular/core/testing';

Затем с помощью TestBed создаем тестовую конфигурацию для нашего компонента:

beforeEach(async () => {

  await TestBed.configureTestingModule({
    declarations: [MyComponent]
  })
  .compileComponents();

});

Теперь можно писать тесты для компонента. Например, простой тест проверки отрисовки:

it('should render title', () => {

  const fixture = TestBed.createComponent(MyComponent);

  fixture.detectChanges();

  const compiled = fixture.nativeElement;

  expect(compiled.querySelector('.title').textContent).toContain('My title');

});

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

Работа с зависимостями и mock-объектами

Компоненты часто используют различные сервисы и зависимости. Чтобы их можно было протестировать, нужно создавать mock-объекты.

Например, компонент использует некий сервис DataService для получения данных:

@Component({/*...*/})
export class MyComponent {

  constructor(private dataService: DataService) {}

  getData() {
    return this.dataService.getSomeData(); 
  }

}

Чтобы протестировать его без реального DataService, можно создать mock-объект:

const mockDataService = {

  getSomeData: () => ['mock'] 

};

TestBed.configureTestingModule({

  providers: [
    {provide: DataService, useValue: mockDataService}
  ]

});

И теперь при вызове getData() будут возвращаться тестовые данные от mock-объекта.

Тестирование шаблона и обработчиков событий

Помимо логики, важно тестировать отображение данных в шаблоне компонента.

Можно проверить, что некий параметр выводится в шаблон:

it('should display user name', () => {

  // установка тестового параметра

  fixture.detectChanges(); 

  expect(compiled.querySelector('.user-name').textContent).toContain('John');

});

А также тестировать обработчики событий, например кликов:

it('should call deleteUser method on delete click', () => {

  const deleteSpy = spyOn(component, 'deleteUser');

  const button = fixture.debugElement.query(By.css('.delete'));

  button.triggerEventHandler('click', null);

  expect(deleteSpy).toHaveBeenCalled();

});

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

Работа с асинхронными операциями

Компоненты часто выполняют асинхронные операции, например запросы к API. Чтобы их протестировать, используются специальные инструменты.

Для тестирования промисов есть async:

it('should load data', async() => {

  const data = await component.getAsyncData();

  expect(data).toBeTruthy();

});

А для тестирования всех асинхронных операций в Angular есть fakeAsync и tick:

it('should load data', fakeAsync(() => {

  component.getAsyncData();

  tick();

  expect(component.data).toBeTruthy(); 

}));

Таким образом можно задать тестовый асинхронный сценарий и проверить результат.

Итог

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