Test-driven JavaScript mit Jasmine
Kommentare

Matchers
Das eigentliche Kernstück der Tests sind die so genannten Matchers. In anderen Systemen werden sie als Assertions bezeichnet. Ein Vergleich beginnt immer mit einem Aufruf von expect. Diese Funktion

Matchers

Das eigentliche Kernstück der Tests sind die so genannten Matchers. In anderen Systemen werden sie als Assertions bezeichnet. Ein Vergleich beginnt immer mit einem Aufruf von expect. Diese Funktion erhält als Parameter den Ausdruck, der überprüft werden soll. Das kann eine Funktion oder aber auch eine Variable oder die Eigenschaft eines Objekts sein. Im Falle einer Funktion wird der Rückgabewert ausgewertet, bei einer Objekteigenschaft oder einer Variablen wird diese direkt geprüft.

Die einfachste Art des Vergleichs ist der toEqual Matcher. Mit ihm wird geprüft, ob der Wert, der expect übergeben wurde, mit seinem Parameter übereinstimmt. Ist das der Fall, gilt der Test als erfolgreich, ansonsten als fehlgeschlagen. Das ist dann auch der erste Schritt, den wir in unserem Beispiel umsetzen. Wir erstellen einen Test, der prüft, ob das Volumen eines Würfels korrekt berechnet wird:

it('can calculate its volume', function () {
   var myCube = new Cube(20);
   expect(myCube.getVolume()).toEqual(8000);
});

Ein Durchlauf dieses ersten Tests liefert ein negatives Ergebnis, da die Funktionalität noch nicht implementiert ist (Abb. 2).

Abb. 2: Der Durchlauf des ersten Tests liefert ein negatives Ergebnis

Im nächsten Schritt wird die getVolume-Methode der Cube-Klasse implementiert, und zwar auf die einfachste Art und Weise. In unserem Fall wäre das eine Methode, die lediglich den erwarteten Wert zurückgibt. Danach werden die Tests erneut durchlaufen. Das Ergebnis sollte diesmal ein erfolgreicher Durchlauf sein. Im dritten Schritt, dem Refactoring, sollte nun die Rückgabe des fixen Werts durch die Berechnung des Volumens des Würfels ausgetauscht werden. Danach erfolgt ein erneuter Durchlauf der Tests. Auf diese Weise lassen sich auch sehr komplexe Algorithmen in kleinen Schritten entwickeln, und der Entwickler hat dabei stets die Gewissheit, dass der bereits implementierte Quellcode genau das tut, was er von ihm erwartet.

Neben dem verwendeten toEqual steht noch eine Reihe weiterer Matcher zur Verfügung, mit denen beispielsweise auf undefined (toBeUndefined()) oder auf boolesche Werte (toBeTruthy()) beziehungsweise (toBeFalsy()) geprüft werden kann. Eine vollständige Liste der existierenden Matcher steht in der Dokumentation von Jasmine zur Verfügung.

Um die Tests besser lesbar zu machen, kann die Bedeutung sämtlicher Matcher durch das Voranstellen von . not umgekehrt werden. Dadurch können unverständliche oder negierte Bedingungen vermieden werden. Konkret lautet die Zeile für ein Ungleich also: expect(x).not.toEqual(y);

Für den Fall, dass die von Jasmine zur Verfügung gestellten Matcher nicht ausreichen, besteht die Möglichkeit, eigene Matcher zu definieren. Diese Aufgabe ist einfach: Neue Matcher werden innerhalb einer Testsuite in der beforeEach– oder einer it-Funktion definiert. Zu diesem Zweck steht die Methode addMatchers zur Verfügung. Sie erhält als Parameter eine Hash-Map mit den Namen der benutzerdefinierten Matcher als Schlüssel und deren Implementierung als Wert. Ein selbst geschriebener Matcher sollte sich in der Benennung nach dem Schema der bereits existierenden Matcher richten. Der Matcher erhält mit der Variablen this.actual den Wert der zuvor aufgerufenen expect-Funktion und kann selbst einen oder mehrere Parameter definieren, die dann auf eine festgelegte Art und Weise mit dem Eingabewert verglichen werden. Der Rückgabewert muss ein boolescher Wert sein. Ist der Vergleich erfolgreich, muss der Matcher true zurückgeben, im Fehlerfall false:

this.addMatchers({
    toMatchCustomized: function(expectedValue) {
        return this.actual === expectedValue;
    }
});

Auf diese Art können auch existierende Matcher überschrieben werden. Das kann nötig sein, wenn die bestehende Funktionalität nicht den Anforderungen des Entwicklers entspricht. Um einen Matcher zu überschreiben, gibt man seinen Namen in der addMatchers-Methode an und definiert eine entsprechende Funktion, die dann die ursprüngliche Funktionalität des Matchers ersetzt.


Themen der kommenden Seiten:

  • Test-Doubles
  • Asynchrone Tests
  • Ausführung im Browser
  • Integration in die IDE
  • Ausblick
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -