Testen in Angular

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ür die Tests, in das die zu testende Komponente eingebettet wird (d.h., die Komponente wird von ihrem eigenen Modul getrennt und in das TestBed eingefügt
  • Über die Methode configureTestingModule kann dem TestBed ein @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 createComponent kann TestBed nicht mehr rekonfiguriert werden
  • createComponent löst nicht automatisch eine change detection aus. Dafür muss eine fixture.detectChanges ausgelöst werden

Automatische change detection:

  • Es gibt allerdings mit ComponentFixtureAutoDetect eine Möglichkeit, gewisse Änderungen automatisch zu bemerken
  • Dies ist allerdings beschränkt: “The ComponentFixtureAutoDetect service 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 call fixture.detectChanges() manually to trigger another cycle of change detection.”
  • Daher sollte grundsätzlich immer fixture.detectChanges() explizit aufgerufen werden