2012-10-10 5 views
12

Ich habe einen Datenbank-Wrapper für meine Anwendung erstellt, siehe unten. Um es zu testen, möchte ich natürlich die eigentliche Datenbankbibliothek ersetzen. Ich könnte eine neue Klasse erstellen, die die query Methode verspottet und alle Eingaben dort fängt, aber sinon.js scheint passender zu sein, aber wie würde ich es verwenden?
Ist die mock oder stub Funktionen von sinon.js was ich verwenden sollte?Eine Klasse in sinon.js stubben und/oder verspotten?

wrapper = (function() { 

    function wrapper() {} 

    wrapper.db = require("database"); 

    wrapper.prototype.insertUser = function(doc) { 
    return this.db.query("INSERT INTO USERS..."); 
    }; 

    return wrapper; 

})(); 

Antwort

6

Sie können beide für das verwenden.

Mock haben ein erwartetes geordnetes Verhalten, das Ihnen, wenn es nicht korrekt befolgt wird, einen Fehler gibt.

Ein Stub ist ähnlich wie ein Schein, aber ohne die Reihenfolge, so können Sie Ihre Methoden so nennen, wie Sie wollen. Meiner Erfahrung nach braucht man fast nie einen Schein.

Beide ersetzen Ihre Methode für eine leere Methode oder eine Schließung, wenn Sie eine übergeben. Es wäre so etwas wie diese:

stub = sinon.stub(wrapper , 'insertUser ', function() { return true; }); 

Dann die Sie hinzufügen, erwarten Verhalten zu überprüfen, ob es passiert ist.

Ich verwende gerne Jasmine mit Jasmine-Sinon für die Überprüfung der Tests.

+0

Oh. Also wäre es besser, die 'insertUser'-Methode statt des' this.db'-Aufrufs, den 'insertUser' ausführt, auszugeben? – Industrial

+2

Hängt davon ab, was Sie testen, aber wenn Sie testen möchten, ob der insertUser in die DB eingefügt wird, wäre dies ein Integrationstest und kein Stubbing würde Sie davon abhalten, die echte Logik mit einigen in der Speicher-DB zu verwenden, um ein Oracle zu "fälschen" Wenn Sie zum Beispiel testen möchten, ob der insertUser bei Bedarf aufgerufen wird, dann könnte die Methode insertUser als Methode verwendet werden. –

8

Zuerst würde ich Ihre Klassendefinition ein bisschen (Großklassennamen und beheben DB-Zuordnung) ändern:

var Wrapper = (function() { 

    function Wrapper() { 
    this.db = require("database"); 
    } 

    Wrapper.prototype.insertUser = function(doc) { 
    return this.db.query("INSERT INTO USERS..."); 
    }; 

    return Wrapper; 

})(); 

die ganze Klasse Stub:

var WrapperStub = sinon.spy(function() { 
    return sinon.createStubInstance(Wrapper); 
}); 

sinon.createStubInstance eine Instanz erstellen Wrapper, wobei jede Methode ein Stub ist. ermöglicht es uns, die Klasseninstanziierung auszuspionieren.

So könnte man es so ausüben:

// verify instantiation 
var wrapper = new WrapperStub(); 
expect(WrapperStub).to.have.been.calledWithNew; 

// verify method stub 
wrapper.insertUser.returns('data'); 
expect(wrapper.insertUser()).to.equal('data'); 
expect(wrapper.insertUser).to.have.been.calledOnce; 

(Behauptungen verwenden chai und sinon-chai)

ich sagte nur "sie ausüben", weil dieser Code-Schnipsel nicht ein tatsächlicher Unit-Test ist. Instanziierungs- und Methodenaufrufe werden von Ihrem Testobjekt durchgeführt.

Nun, wenn Sie wollen eine Abhängigkeit von erfordern injiziert verspotten() -such als db = require('database') in Ihrer Beispiel-, können Sie ein Test-Tool wie entweder Jest versuchen könnte (aber mit sinon nicht) oder sinonquire, die ich von inspiriert erstellt Jest aber es mit sinon plus Ihr Lieblingstestwerkzeug zu benutzen (meins ist Mokka). Intern verwendet sinonquire die gleiche oben gezeigte Technik, und sinon.createStubInstance zu kombinieren, um eine Klasse zu stubben.

+0

Aktualisierte Links zu Jest: https://facebook.github.io/jest/docs/mock -functions.html http://facebook.github.io/jest/docs/jest-object.html#jestenableautomock – jwadsack

Verwandte Themen