Unit-Testing für JavaScript: Jasmine als Basis für Jest

Jest basiert auf dem relativ bekannten Test-Framework Jasmine, kann aber Einiges mehr. Neben den Basis-Features von Jasmine ist Jest auch in der Lage, eine ganze Reihe von Vorgängen zu automatisieren. So ist Jest in der Lage, selbstständig alle Tests in einem Repository zu finden, oder Mock-Objekte ganz automatisch zu generieren zu, damit du deinen Code schneller Testen kannst – ohne irgendwelche Abhängigkeiten berücksichtigen zu müssen.

Jest erweitert das bekannte Testing-Framwork Jasmine. (Grafik: Facebook)

Jest kann über ein Commando-Tool genutzt werden, denn das Framework durchläuft Tests auf einem Fake-DOM, und das paralell.

In vier Schritten: Jest anwenden

Das folgende Beispiel geht davon aus, dass ihr die sum.js-Klasse testen wollt, die nichts anders macht, als zwei Werte zu addieren.

// sum.js
function sum(value1, value2) {
  return value1 + value2;
}
module.exports = sum;

Um einen Test zu entwicklen, müsst ihr folgende Test-Datei im Verzeichnis tests/ hinterlegen:

// __tests__/sum-test.js
jest.dontMock('../sum');

describe('sum', function() {
 it('adds 1 + 2 to equal 3', function() {
   var sum = require('../sum');
   expect(sum(1, 2)).toBe(3);
 });
});

Mit npm install jest-cli --save-dev könnt ihr das Command-Tool starten. Wenn ihr eure package.json aktualisiert mit ...

{
 ...
 "scripts": {
   "test": "jest"
 }
 ...
}

... aktualisiert, könnt ihr den Test via npm test ausführen.

Automatische Mock-Objekte

Ein Grundprinzip des Unit-Testings ist, dass man nur eine „Unit“ testet. Nun ist es aber so, dass diese Einheiten von anderer Software abhängig ist und auf „Modul-Größe“ heranwachsen kann. Und genau hier liegt die Stärke von Jest. Das Test-Framework macht es extrem einfach, einzelne Module von Abhängigkeiten zu isolieren und diese zu testen – völlig automatisiert. Jest generiert somit selbstständig Mock-Objekte um die Funktionstüchtigkeit einzelner Module, ohne die eigentlichen Abhängigkeiten, testen zu können. Hier ein Beispiel:

// CurrentUser.js
var userID = 0;
module.exports = {
  getID: function() { 
    return userID;
  },
  setID: function(id) {
    userID = id;
  }
};
// login.js
var CurrentUser = require('./CurrentUser.js');

Wenn ihr die long.js-Datei mit NodeJS ausführt, wird Jest nicht eingreifen, jedoch: Ein Unit-Test für login.js veranlasst Jest, die require()-Methode zu verändern. Nämlich so, dass sich der Code wie folgt verhält:

var CurrentUser = {
  getID: jest.genMockFunction(),
  setID: jest.genMockFunction()
};

Durch diese Anpassung wird die „echte“ Current.js-Datei durch Mock-Objekte ersetzt. Der zu testende Code ist also isoliert worden, kann aber trotzdem uneingeschränkt getestet werden. Somit müssen keine zusätzlichen „Boilerplates“ entwickelt werden, nur für Abhängigkeiten, die ihr sowieso nicht einem Test unterziehen wolltet.

Jest ist sinnvolle Alternative zu Jasmine

Es ist ein guter Ansat, vieles in einem Framework bereitzustellen, aber Entwicklern trotzdem die Möglichkeit zu bieten, in Einzelfällen anders vorgehen zu können – ganz ohne „dirty hacks“.

Gerade die Mockup-Funktion bei Jest ist eine solche Möglichkeit. Durch die jest.mock()- und jest.dontMock()-APIs könnt ihr bestimmen wie sich Mock-Objekt verhalten. Zusätzlich können in Jest – in speziellen Fällen – völlig neue und eigene Mock-Objekte manuell implementiert werden.

Wenn ihr mehr über Jest erfahren wollt, dann kann ich euch die Dokumentation empfehlen. Das Test-Framework könnt ihr bei GitHub herunterladen. Hier findet ihr ähnliche Artikel zu Frameworks wie Jest.

Was sagt ihr zu Facebooks JavaScript-Unit-Testing?

Outbrain