2016-08-10 4 views
0

gelten folgende Voraussetzungen Klasse ändertWie Einheit, um eine Funktion testen, die nur interner Zustand

class Observable() { 
    constructor() { this._cbs = []; } 

    on(cb) { 
     this._cbs.push(cb); 
    } 

    off(cb) { 
     this._cbs.splice(this._cbs.indexOf(cb)); 
    } 

    trigger() { 
     this._cbs.forEach((cb) => cb()); 
    } 
} 

Wie soll ich Unit-Test die on Methode. Jetzt konnte ich das this._cbs Array untersuchen und einfach überprüfen, ob der Callback darauf geschoben wurde. Aber wenn ich das tue, wende ich Implementierungswissen zu meinen Tests an. Oder ich könnte den Callback ausspionieren und trigger anrufen und prüfen, ob der Callback angerufen wird oder nicht. Dies ist jedoch kein Integrationstest.

Also, was wäre im Allgemeinen der Ansatz für Unit-Test-Funktion, die nur interne Effekte haben?

+0

Wenn die getestete Klasse den beobachtbaren Zustand des Systems ändert (in Ihrem Fall eine Eigenschaft), können Sie die vorgenommenen Änderungen bestätigen. – kayess

+0

was ist mit einem Spion? –

+1

Die einzige Operation in der on-Methode ist die Verwendung der Funktion 'Array.prototype.push', die Teil der JavaScript-Sprache ist. Sie müssen nicht testen, dass 'push' richtig funktioniert, weil es Teil der Sprache ist. Das Einzige, was du überprüfen kannst, ist das Ergebnis, das du erwähnt hast. – TW80000

Antwort

1

Ich denke, dass, wenn Ihre Methode nur internen Zustand ändert, der einzige Weg, um sicherzustellen, dass durch öffentlich zugängliche Methoden wäre (zB wenn Ihre Klasse eine .count() Funktion hat, dass danach überprüfen kannst.)

Ohne äußeres Mechanismus zur Überprüfung der internen Operation ist sehr schwer zu überprüfen.

Manchmal in C#, wenn das wirklich wichtig Logik war, würde ich das [InternalsVisibleTo] Attribut verwenden, um (in Ihrem Fall _cbs) den internen Zustand der Klasse zu überprüfen.

Alternativ, wenn dies keine sehr wichtige Funktionalität war, kann es ausreichen zu wissen, dass eine Funktion aufgerufen wurde. In diesem Beispiel könnten Sie also einen gespiegelten _cbs als Parameter angeben und prüfen, ob .push() aufgerufen wurde.

1

In diesem Fall ist Ihre aggregate die Klasse Observable, die eine invariant namens _cbs hat. Jetzt ist der einzige Geschäftswert, gegen den Sie Ihre System Under Test testen könnten, die Geschäftslogik, die auf die Invariante zugreift, die den Zustand des beobachtbaren Systems ändert, dh das Ergebnis des Flusses der aufgerufenen Geschäftslogik zu bestätigen.

Verwandte Themen