Testen in Angular #
Isolierte Unit Tests:
- Untersuchen Instanz einer Klasse ohne ihre Abhängigkeiten (zu Angular, zu injizierten Klassen etc.)
- Vorgehen: Erstellen einer Testinstanz mit
new, ev. Testdouble für den Konstruktor, untersuchen der öffentlichen Methoden und Properties - V.a. geeignet für Pipes und Services, z.T. auch für Komponenten, doch besteht hier das Problem, dass sie nicht in ihrem Zusammenspiel mit dem Framework getestet werden können
- Benötigen die Angular testing utilities
Starten des Karma Testframeworks:
npm test bzw. ng t
Eine basales Testfile (Beispiel):
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { BannerInlineComponent } from './banner-inline.component';
describe('BannerComponent (inline template)', () => {
let comp: BannerComponent;
let fixture: ComponentFixture<BannerComponent>;
let de: DebugElement;
let el: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
});
fixture = TestBed.createComponent(BannerComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css('h1'));
el = de.nativeElement;
}));
// Hier folgen die Tests
});
TestBed:
- Erstellt ein Modul (
@NgModule)fürdie Tests, in das die zu testende Komponente eingebettet wird (d.h., die Komponente wird von ihrem eigenen Modul getrennt und in dasTestBedeingefügt - Über die Methode
configureTestingModulekann demTestBedein@NgModule-ähnliches Metadaten-Objekt übergeben werden. Dabei werden die meisten Eigenschaften eines “echten” Metadaten-Objektes unterstützt
beforeEach:
- Diese Methode sorgt dafür, dass das Testmodul sich nach jedem Test auf die Basiseinstellungen zurückgesetzt wird
createComponent:
- Erstellt eine Instanz der zu testenden Komponente und retourniert in diesem Beispiel eine “component test fixture”
- Nach dem Aufruf der Methode
createComponentkannTestBednicht mehr rekonfiguriert werden createComponentlöst nicht automatisch eine change detection aus. Dafür muss einefixture.detectChangesausgelöst werden
Automatische change detection:
- Es gibt allerdings mit
ComponentFixtureAutoDetecteine Möglichkeit, gewisse Änderungen automatisch zu bemerken - Dies ist allerdings beschränkt: “The
ComponentFixtureAutoDetectservice responds to asynchronous activities such as promise resolution, timers, and DOM events. But a direct, synchronous update of the component property is invisible. The test must callfixture.detectChanges()manually to trigger another cycle of change detection.” - Daher sollte grundsätzlich immer
fixture.detectChanges()explizit aufgerufen werden