2017-03-16 3 views
0

Ich habe eine Klasse, die ein Bild laden, schließen oder umbenennen kann (zumindest für den Moment wird es mehr Operationen mit geöffneten Datei in Zukunft geben).Testen Stateful Klassen

Ich habe es mit Facade-Muster implementiert (ich denke schon).

Als ich versuchte, Tests dafür zu schreiben, habe ich schnell gemerkt, dass ich es mit anderen Voraussetzungen testen muss (zum Beispiel wenn das Bild vor dem Aufruf einer Methode geladen wurde). Und die Menge der Tests ist riesig und wird sehr schnell wachsen, wenn ich neue Operationen hinzufüge. Nach meinem Verständnis sind dies keine Unit-Tests, sondern End-to-End-Tests.

Ich bin neu bei TDD, also kann mir jemand sagen, ist es normale Praxis, solche komplizierten Tests zu haben?

Ich erwarte Antworten zu zu viel Verantwortung meiner Klasse, aber lässt über Alternativen denken:

// pseudo-code 

// #1 - my way 
function onRenameButtonClick(newName) { 
    imageFacade.rename(newName) 
} 

// #2 - the other way 
function onRenameButtonClick(newName) { 
    if (imageController.isOpened()) { 
    imageRenamer.rename(imageController.image, newName) 
    } 
} 

Am Ende muss ich noch für 2 # richtige Verhalten testen, und es wird immer noch mit einbeziehen unterschiedliche Voraussetzungen.

Wie gehen Sie mit solchen Fällen um? Ist das normal oder mache ich etwas falsch?

P. S. hier ist ein Skelett meiner Fassade Klasse, beachten Sie, dass in config gibt es reine Funktionen, die tatsächlich arbeiten, und actions sind diese reinen Funktionen zusammenfügen und lösen Ereignisse abhängig vom Zustand.

function makeImageWTF(loader, renamer) { 
    return { 
    state: { 
     image: null, 
     filePath: null, 
     isLoading: false 
    }, 
    config: { 
     loader, 
     renamer 
    }, 
    triggers: { 
     opening: new Bus(), 
     opened: new Bus(), 
     closed: new Bus(), 
     renamed: new Bus(), 
     error: new Bus() 
    }, 
    actions: { 
     open: function(path) {}, 
     close: function() {}, 
     rename: function(newName) {} 
    } 
    } 
} 

Und hier ist ein Skelett von Tests

describe('ImageWTF', function() { 
    describe('initial state', function() { 
    it('should be that', function() { 
     var wtf = makeImageWTF() 
     assert.deepEqual({ 
     image: null, 
     filePath: null, 
     isLoading: false, 
     }, wtf.state) 
    }) 
    }) 

    describe('#open(path)', function() { 
    it('sets isLoading') 
    it('calls config.loader with path') 
    it('sets image, fileName') 
    it('triggers loading, loaded or error') 
    it('clears isLoading') 
    }) 

    describe('#close()', function() { 
    describe('when image is opened', function() { 
     it('resets image') 
     it('triggers closed') 
    }) 

    describe('when image is NOT opened', function() { 
     it('triggers error') 
    })  
    }) 

    describe('#rename()', function() { 
    describe('when image is opened', function() { 
     it('calls config.renamer with oldName and newName') 
     it('sets fileName') 
     it('triggers renamed') 
    }) 

    describe('when image is NOT opened', function() { 
     it('triggers error') 
    }) 
    }) 
}) 

Antwort

0

(Einheit) Test wie Produktionscode ist - sie kompliziert werden können. Aber das Ziel sollte natürlich sein, sie so einfach wie möglich zu halten.

Wenn Sie noch keinen Test für Ihren Code haben, schlage ich vor, dass Sie einen Test schreiben, um die wichtigsten Anwendungsfälle abzudecken. Sobald Sie diese an Ort und Stelle haben, können Sie sie umgestalten. Aber für mich würde der Hauptfokus darauf liegen, einen Test an Ort und Stelle zu bekommen, Sie werden viel lernen, wenn Sie diesen Weg gehen.

Es würde mir nicht viel ausmachen, wenn sie nicht von Anfang an "Komponententest" sind, ändern Sie sie für Ihre Anwendung.

Versuchen Sie, die Tests nicht mit dem Produktionscode zu koppeln, da Sie die Flexibilität haben möchten, den Produktionscode umzuformen, ohne die Tests gleichzeitig zu ändern (und umgekehrt). Komponententest bedeutet für mich, den Code einfach und schnell zu ändern und zu refaktorieren. Sie werden nicht alle Fehler oder Verhalten in Ihrer Anwendung abfangen - dafür müssen Sie sich auch auf andere Arten von Tests konzentrieren.