GEDOPLAN
Webprogrammierung

Angular Testing mit Spies

Webprogrammierung
question 2736480 1280 1

Unit Testing gehört zum guten Ton eines jeden Projektes. Angular tut sein bestes um es dem Entwickler so leicht wie möglich zu machen dieses Thema im Projektalltag unter zu bringen. Es existieren mehrere Möglichkeiten Komponenten losgelöst zu testen. Eine davon: ‘Spies’

question 2736480 1280

Schauen wir uns zuerst noch einmal kurz in groben Zügen das Testing von Angular an sich an ( weiterer Blog beitrag zu diesem Thema hier ) . Sofern wir es nicht deaktiviert haben generiert die Angular CLI zu jeden unserer Komponenten, Service etc. eine zusätzliche TypeScript Datei mit der Dateiendung: spec.ts . Diese Datei ist der Ausgangspunkt unseres Unit-Tests und enthält einen ersten sehr rudimentären Test ob die Komponente erstellt werden kann:

describe('LocalStorageTextAreasComponent', () => {
  let component: LocalStorageTextAreasComponent;
  let fixture: ComponentFixture<LocalStorageTextAreasComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ LocalStorageTextAreasComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LocalStorageTextAreasComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Schauen wir uns die wichtigen Bestandteile noch mal an und machen uns klar welche Aufgabe sie haben:

TestBed . Erzeugt ein eigenständiges NGModul welches zum Testen herrangezogen wird. Das bedeutet das wir hier wie gewohnt mit declarations, imports und providers deklarieren was wir verwenden wollen. Im Fall unserer Unit Tests besteht hier z.B. die Möglichkeit Objekte die wir per DI erhalten zu mocken:

    TestBed.configureTestingModule({
      providers: [
        { provide: RecordService, useValue: { save: () => { } } },
        { provide: ProjectService, useValue: { getAll: () => { } } },
      ]
    })

fixture.componentInstance liefert uns dann die konkrete Instanz die wir zum Testen herran ziehen können. Diese Komponente hat natürlich unter umständen Abhänigkeiten und verwendet z.B. Services die bei unseren Tests in aller Regel nicht aufgerufen werden sollen: wir wollen ja unsere Komponente testen und nicht die Services die sie verwendet. Neben der Erzeugung eines kompletten Mock-Objektes und die Verwendung mittels providers-Array existiert noch die Möglichkeit einen Spy zu verwenden. Quasi ein “Beobachter” der für Methoden registriert wird und über den wir dann,zum einen, Prüfen können ob die Methoden aufgerufen wurden und zum anderen können wir auch dafür sorgen das Test-Werte geliefert werden anstatt den Aufruf an die echte Methode zu delegieren.

  it('close should save', () => {
    const emitSpy = spyOn(component.saved, 'emit');

    const saveSpy = spyOn(component['recordService'], 'save').and.returnValue(of({ id: 100 }));

    component.form.get('id').setValue(null);
    component.form.get('start').setValue(new Date());

    component.beforeunload(null);
    expect(saveSpy).toHaveBeenCalled();
    expect(emitSpy).toHaveBeenCalledWith({ id: 100 });

  });

Zwei Beispiel dafür sehen wir hier. Zeile 2 registriert einen Spy der auf die “save” Methode der zu testen Komponente registriert wird. Wir lassen den Aufruf zu dieser Methode zu, können aber über den Spy am Ende prüfen ( Zeile 11 ) ob die Methode aufgerufen wurde + bei Bedarf unter Angabe von konkreten Parametern die wir erwarten.

Zeile 4 zeigt nun die Verwendung von einem Spy um Service-Aufrufe zu unterbinden. Ähnlich wie im ersten Beispiel registrieren wir uns mittels spyOn Methode unter Angabe des Objektes und dem Namen der Methode. Hier verknüpfen wir den Spy jedoch mittels and.returnValue und liefern dann ein Observable der ein Dummy-Objekt zurück liefert. Damit können wir die Komponente testen ohne das die Service-Methode aufgerufen wird.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!