Тестування в Angular (модульні та інтеграційні тести)
Тестування в Angular
Angular має вбудовану тестову систему, що використовує Jasmine (тестовий запускник) і Karma (браузерний запускник), з TestBed для налаштування тестових модулів. Сучасні проекти часто використовують Jest як альтернативу.
Налаштування TestBed
typescript
import { ComponentFixture, TestBed } from '@angular/core/testing';
describe('UserComponent', () => {
let component: UserComponent;
let fixture: ComponentFixture<UserComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [UserComponent], // Самостійний компонент
providers: [
{ provide: UserService, useValue: mockUserService }
]
}).compileComponents();
fixture = TestBed.createComponent(UserComponent);
component = fixture.componentInstance;
fixture.detectChanges(); // Запустити початкове виявлення змін
});
it('повинен створити', () => {
expect(component).toBeTruthy();
});
});Тестування компонентів
typescript
it('повинен відображати ім\'я користувача', () => {
component.user = { name: 'Alice', email: 'alice@test.com' };
fixture.detectChanges();
const nameEl = fixture.nativeElement.querySelector('h1');
expect(nameEl.textContent).toContain('Alice');
});
it('повинен генерувати подію при натисканні кнопки', () => {
spyOn(component.delete, 'emit');
const button = fixture.nativeElement.querySelector('.delete-btn');
button.click();
expect(component.delete.emit).toHaveBeenCalledWith(component.user.id);
});Тестування сервісів
typescript
describe('UserService', () => {
let service: UserService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
UserService,
provideHttpClient(),
provideHttpClientTesting(),
]
});
service = TestBed.inject(UserService);
httpMock = TestBed.inject(HttpTestingController);
});
afterEach(() => {
httpMock.verify(); // Переконатися, що немає незавершених запитів
});
it('повинен отримувати користувачів', () => {
const mockUsers = [{ id: '1', name: 'Alice' }];
service.getUsers().subscribe(users => {
expect(users.length).toBe(1);
expect(users[0].name).toBe('Alice');
});
const req = httpMock.expectOne('/api/users');
expect(req.request.method).toBe('GET');
req.flush(mockUsers); // Надати мок-відповідь
});
});Мокування залежностей
typescript
// Створити мок-сервіс
const mockUserService = {
getUsers: jasmine.createSpy().and.returnValue(of([{ name: 'Alice' }])),
deleteUser: jasmine.createSpy().and.returnValue(of(void 0)),
};
// Або використати jasmine.createSpyObj
const mockAuth = jasmine.createSpyObj('AuthService', ['login', 'logout', 'isLoggedIn']);
mockAuth.isLoggedIn.and.returnValue(true);
// Надати в TestBed
providers: [
{ provide: UserService, useValue: mockUserService },
{ provide: AuthService, useValue: mockAuth },
]Тестування асинхронного коду
typescript
it('повинен завантажити користувачів при ініціалізації', fakeAsync(() => {
component.ngOnInit();
tick(300); // Симулювати затримку
fixture.detectChanges();
expect(component.users.length).toBe(1);
}));
it('повинен обробляти асинхронну операцію', async () => {
await component.loadData();
fixture.detectChanges();
expect(component.data).toBeTruthy();
});Найкращі практики тестування
| Практика | Чому |
|---|---|
| Мокувати зовнішні залежності | Ізолювати одиницю, що тестується |
Використовувати fixture.detectChanges() | Запустити виявлення змін Angular |
| Тестувати поведінку, а не реалізацію | Тести витримують рефакторинг |
Використовувати fakeAsync + tick | Контролювати асинхронний час |
httpMock.verify() в afterEach | Виявляти несподівані HTTP виклики |
| Тестувати крайні випадки | Порожні дані, помилки, стани завантаження |
Важливо:
Тестування в Angular використовує TestBed для налаштування тестового модуля з компонентами, сервісами та моками. Мок-сервіси для ізоляції одиниць, використовуйте HttpTestingController для HTTP тестів, а також fakeAsync/tick для асинхронних операцій. Завжди викликайте fixture.detectChanges() після зміни даних. Зосередьтеся на тестуванні поведінки — те, що бачить і робить користувач.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.