Angular предоставляет встроенный инструмент для модульного
тестирования компонентов и сервисов — 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);
}));
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 и встроенные утилиты предоставляют полный инструментарий для надёжного, модульного и интеграционного тестирования, обеспечивая стабильность приложения при изменениях и масштабировании.