Testowanie inputów, outputów i DOM
Sprawdzać wyrenderowaną zawartość i zdarzenia
Testowanie inputów, outputów i DOM to bezpłatna lekcja Angular Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Angular Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Angular Academy zawiera 4 lekcji w sumie.
Testowanie kontraktu komponentu
Komponenty komunikują się za pomocą inputs (dane wejściowe), outputs (zdarzenia wyjściowe) oraz wyrenderowanego DOM-u. Dobre testy komponentu korzystają z tych trzech interfejsów i sprawdzają widoczny rezultat, a nie szczegóły implementacji wewnętrznej.
Ustawianie danych wejściowych
Należy przypisać wartość do właściwości wejściowej instancji komponentu, a następnie wywołać detectChanges(), aby ponownie wykonać renderowanie. W przypadku signal inputs wartość ustawia się za pomocą fixture.componentRef.setInput().
fixture.componentInstance.label = 'Save';
fixture.detectChanges();
// signal inputs:
fixture.componentRef.setInput('label', 'Save');
fixture.detectChanges();Odczytywanie DOM-u za pomocą querySelector
Należy użyć fixture.nativeElement.querySelector(), aby znaleźć wyrenderowane elementy i sprawdzić ich tekst lub atrybuty.
fixture.componentRef.setInput('label', 'Save');
fixture.detectChanges();
const btn = fixture.nativeElement.querySelector('button');
expect(btn.textContent.trim()).toBe('Save');DebugElement i By.css
fixture.debugElement.query(By.css(...)) zwraca wrapper DebugElement. Jego .nativeElement jest węzłem DOM, a dodatkowo udostępnia bogatsze zapytania działające na różnych platformach.
import { By } from '@angular/platform-browser';
const de = fixture.debugElement.query(By.css('.title'));
expect(de.nativeElement.textContent).toContain('Hello');queryAll dla list
W przypadku powtarzających się elementów (np. pętli @for) należy użyć queryAll, aby pobrać wszystkie dopasowania i sprawdzić ich liczbę.
const items = fixture.debugElement.queryAll(By.css('li'));
expect(items.length).toBe(3);
expect(items[0].nativeElement.textContent).toContain('First');Symulowanie kliknięcia
Należy wywoływać zdarzenia DOM, aby testować interakcję. Można użyć triggerEventHandler na obiekcie DebugElement albo natywnego .click(), a następnie detectChanges().
const btn = fixture.debugElement.query(By.css('button'));
btn.triggerEventHandler('click');
fixture.detectChanges();
expect(fixture.componentInstance.count).toBe(1);Testowanie zdarzenia wyjściowego
Należy zasubskrybować wyjście komponentu (EventEmitter lub sygnał output) przed wywołaniem działania, które powinno je wyemitować.
let emitted: string | undefined;
fixture.componentInstance.saved.subscribe((v: string) => (emitted = v));
fixture.debugElement.query(By.css('button')).triggerEventHandler('click');
expect(emitted).toBe('done');Sprawdzanie atrybutów i klas
Można sprawdzać warunkowe klasy i atrybuty zależne od danych wejściowych.
fixture.componentRef.setInput('active', true);
fixture.detectChanges();
const el = fixture.nativeElement.querySelector('.tab');
expect(el.classList.contains('active')).toBe(true);Aktualizowanie danych wejściowych formularza
Aby testować pola tekstowe, należy ustawić wartość wejściową i wysłać zdarzenie input, aby wiązania Angulara zostały zaktualizowane.
const input = fixture.nativeElement.querySelector('input');
input.value = 'hello';
input.dispatchEvent(new Event('input'));
fixture.detectChanges();
expect(fixture.componentInstance.text).toBe('hello');Dlaczego po każdej zmianie należy wywoływać detectChanges
Testy oparte na Zone i testy bez Zone wymagają jawnego wywołania detectChanges() po zmianie stanu, ponieważ test jest wykonywany poza automatycznym cyklem Angulara. Pominięcie tego wywołania jest główną przyczyną sytuacji, w której „asercja widzi nieaktualny DOM”.
Testowanie zachowania, nie wnętrza
Należy preferować sprawdzanie wyrenderowanego wyniku i wyemitowanych zdarzeń zamiast prywatnych pól. Dzięki temu testy są odporne na zmiany: refaktoryzacja wnętrza nie powinna psuć testu, jeśli zachowanie widoczne dla użytkownika pozostaje takie samo.
Szybkie sprawdzenie
Które API udostępnia obiekt DebugElement?
Podsumowanie
Ustawiano dane wejściowe za pomocą setInput, odczytywano DOM przy użyciu querySelector i By.css, przechwytywano dane wyjściowe przez subskrypcję oraz symulowano kliknięcia i zdarzenia input. Po każdej zmianie należy zawsze wywołać detectChanges() i sprawdzać zachowanie widoczne dla użytkownika.
Często zadawane pytania
Czy lekcja „Testowanie inputów, outputów i DOM” jest bezpłatna?
Tak — pełny tekst „Testowanie inputów, outputów i DOM” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Angular Academy, przejdź na CoddyKit PRO. Kurs Angular Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Testowanie inputów, outputów i DOM”?
Sprawdzać wyrenderowaną zawartość i zdarzenia Ćwiczysz Angular Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Angular Academy?
Nie wymagamy żadnego doświadczenia. Angular Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Testowanie inputów, outputów i DOM”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Angular Academy?
Tak. Każda lekcja Angular Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- TestBed i elementy testowe komponentów
- Testowanie inputów, outputów i DOM
- Mockowanie serwisów i zależności
- Testowanie signals i kodu asynchronicznego